diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index f6a67906..79af32da 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -d59fb1fec8d9a8ed4eabd956cfe43bfca70e444420b61ab575b8cb194c409d6e /usr/local/bin/tox-bootstrapd +d2f8e02aeb249b0a22d4a7dee087d5f1301385587cb528e9ae055a6ceb2c4567 /usr/local/bin/tox-bootstrapd diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 6042fd72..96aeaa62 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -1837,7 +1837,7 @@ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const u } non_null(1, 3) nullable(5) -static int handle_custom_lossless_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length, +static int m_handle_custom_lossless_packet(void *object, int friend_num, const uint8_t *packet, uint16_t length, void *userdata) { Messenger *m = (Messenger *)object; @@ -1854,7 +1854,7 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin m->lossless_packethandler(m, friend_num, packet[0], packet, length, userdata); } - return 1; + return 0; } void custom_lossless_packet_registerhandler(Messenger *m, m_friend_lossless_packet_cb *lossless_packethandler) @@ -1922,6 +1922,7 @@ static void check_friend_request_timed_out(Messenger *m, uint32_t i, uint64_t t, } } +non_null(1) nullable(4) static int m_handle_status(void *object, int i, bool status, void *userdata) { Messenger *m = (Messenger *)object; @@ -1937,6 +1938,313 @@ static int m_handle_status(void *object, int i, bool status, void *userdata) return 0; } +non_null(1, 3) nullable(5) +static int m_handle_packet_offline(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length == 0) { + set_friend_status(m, i, FRIEND_CONFIRMED, userdata); + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_nickname(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length > MAX_NAME_LENGTH) { + return 0; + } + + /* Make sure the NULL terminator is present. */ + VLA(uint8_t, data_terminated, data_length + 1); + memcpy(data_terminated, data, data_length); + data_terminated[data_length] = 0; + + /* inform of namechange before we overwrite the old name */ + if (m->friend_namechange != nullptr) { + m->friend_namechange(m, i, data_terminated, data_length, userdata); + } + + memcpy(m->friendlist[i].name, data_terminated, data_length); + m->friendlist[i].name_length = data_length; + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_statusmessage(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length > MAX_STATUSMESSAGE_LENGTH) { + return 0; + } + + /* Make sure the NULL terminator is present. */ + VLA(uint8_t, data_terminated, data_length + 1); + memcpy(data_terminated, data, data_length); + data_terminated[data_length] = 0; + + if (m->friend_statusmessagechange != nullptr) { + m->friend_statusmessagechange(m, i, data_terminated, data_length, userdata); + } + + set_friend_statusmessage(m, i, data_terminated, data_length); + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_userstatus(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length != 1) { + return 0; + } + + const Userstatus status = (Userstatus)data[0]; + + if (status >= USERSTATUS_INVALID) { + return 0; + } + + if (m->friend_userstatuschange != nullptr) { + m->friend_userstatuschange(m, i, status, userdata); + } + + set_friend_userstatus(m, i, status); + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_typing(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length != 1) { + return 0; + } + + const bool typing = data[0] != 0; + + set_friend_typing(m, i, typing); + + if (m->friend_typingchange != nullptr) { + m->friend_typingchange(m, i, typing, userdata); + } + + return 0; +} + +non_null(1, 3) nullable(6) +static int m_handle_packet_message(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, const Message_Type message_type, void *userdata) +{ + if (data_length == 0) { + return 0; + } + + const uint8_t *message = data; + const uint16_t message_length = data_length; + + /* Make sure the NULL terminator is present. */ + VLA(uint8_t, message_terminated, message_length + 1); + memcpy(message_terminated, message, message_length); + message_terminated[message_length] = 0; + + if (m->friend_message != nullptr) { + m->friend_message(m, i, message_type, message_terminated, message_length, userdata); + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_invite_conference(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length == 0) { + return 0; + } + + if (m->conference_invite != nullptr) { + m->conference_invite(m, i, data, data_length, userdata); + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_file_sendrequest(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + const unsigned int head_length = 1 + sizeof(uint32_t) + sizeof(uint64_t) + FILE_ID_LENGTH; + + if (data_length < head_length) { + return 0; + } + + const uint8_t filenumber = data[0]; + +#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES + + if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { + return 0; + } + +#endif + + uint64_t filesize; + uint32_t file_type; + const uint16_t filename_length = data_length - head_length; + + if (filename_length > MAX_FILENAME_LENGTH) { + return 0; + } + + memcpy(&file_type, data + 1, sizeof(file_type)); + file_type = net_ntohl(file_type); + + net_unpack_u64(data + 1 + sizeof(uint32_t), &filesize); + struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; + + if (ft->status != FILESTATUS_NONE) { + return 0; + } + + ft->status = FILESTATUS_NOT_ACCEPTED; + ft->size = filesize; + ft->transferred = 0; + ft->paused = FILE_PAUSE_NOT; + memcpy(ft->id, data + 1 + sizeof(uint32_t) + sizeof(uint64_t), FILE_ID_LENGTH); + + VLA(uint8_t, filename_terminated, filename_length + 1); + const uint8_t *filename = nullptr; + + if (filename_length > 0) { + /* Force NULL terminate file name. */ + memcpy(filename_terminated, data + head_length, filename_length); + filename_terminated[filename_length] = 0; + filename = filename_terminated; + } + + uint32_t real_filenumber = filenumber; + real_filenumber += 1; + real_filenumber <<= 16; + + if (m->file_sendrequest != nullptr) { + m->file_sendrequest(m, i, real_filenumber, file_type, filesize, filename, filename_length, + userdata); + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_file_control(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length < 3) { + return 0; + } + + // On the other side, "outbound" is "inbound", i.e. if they send 1, + // that means "inbound" on their side, but we call it "outbound" + // here. + const bool outbound = data[0] == 1; + const uint8_t filenumber = data[1]; + const uint8_t control_type = data[2]; + +#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES + + if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { + return 0; + } + +#endif + + if (handle_filecontrol(m, i, outbound, filenumber, control_type, data + 3, data_length - 3, userdata) == -1) { + // TODO(iphydf): Do something different here? Right now, this + // check is pointless. + return 0; + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_file_data(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length < 1) { + return 0; + } + + const uint8_t filenumber = data[0]; + +#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES + + if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { + return 0; + } + +#endif + + struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; + + if (ft->status != FILESTATUS_TRANSFERRING) { + return 0; + } + + uint64_t position = ft->transferred; + uint32_t real_filenumber = filenumber; + real_filenumber += 1; + real_filenumber <<= 16; + uint16_t file_data_length = data_length - 1; + const uint8_t *file_data; + + if (file_data_length == 0) { + file_data = nullptr; + } else { + file_data = data + 1; + } + + /* Prevent more data than the filesize from being passed to clients. */ + if ((ft->transferred + file_data_length) > ft->size) { + file_data_length = ft->size - ft->transferred; + } + + if (m->file_filedata != nullptr) { + m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); + } + + ft->transferred += file_data_length; + + if (file_data_length > 0 && (ft->transferred >= ft->size || file_data_length != MAX_FILE_DATA_SIZE)) { + file_data_length = 0; + file_data = nullptr; + position = ft->transferred; + + /* Full file received. */ + if (m->file_filedata != nullptr) { + m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); + } + } + + /* Data is zero, filetransfer is over. */ + if (file_data_length == 0) { + ft->status = FILESTATUS_NONE; + } + + return 0; +} + +non_null(1, 3) nullable(5) +static int m_handle_packet_msi(Messenger *m, const int i, const uint8_t *data, const uint16_t data_length, void *userdata) +{ + if (data_length == 0) { + return 0; + } + + if (m->msi_packet != nullptr) { + m->msi_packet(m, i, data, data_length, m->msi_packet_userdata); + } + + return 0; +} + +non_null(1, 3) nullable(5) static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t len, void *userdata) { if (len == 0) { @@ -1958,298 +2266,34 @@ static int m_handle_packet(void *object, int i, const uint8_t *temp, uint16_t le } switch (packet_id) { - case PACKET_ID_OFFLINE: { - if (data_length > 0) { - break; - } - - set_friend_status(m, i, FRIEND_CONFIRMED, userdata); - break; - } - - case PACKET_ID_NICKNAME: { - if (data_length > MAX_NAME_LENGTH) { - break; - } - - /* Make sure the NULL terminator is present. */ - VLA(uint8_t, data_terminated, data_length + 1); - memcpy(data_terminated, data, data_length); - data_terminated[data_length] = 0; - - /* inform of namechange before we overwrite the old name */ - if (m->friend_namechange != nullptr) { - m->friend_namechange(m, i, data_terminated, data_length, userdata); - } - - memcpy(m->friendlist[i].name, data_terminated, data_length); - m->friendlist[i].name_length = data_length; - - break; - } - - case PACKET_ID_STATUSMESSAGE: { - if (data_length > MAX_STATUSMESSAGE_LENGTH) { - break; - } - - /* Make sure the NULL terminator is present. */ - VLA(uint8_t, data_terminated, data_length + 1); - memcpy(data_terminated, data, data_length); - data_terminated[data_length] = 0; - - if (m->friend_statusmessagechange != nullptr) { - m->friend_statusmessagechange(m, i, data_terminated, data_length, userdata); - } - - set_friend_statusmessage(m, i, data_terminated, data_length); - break; - } - - case PACKET_ID_USERSTATUS: { - if (data_length != 1) { - break; - } - - const Userstatus status = (Userstatus)data[0]; - - if (status >= USERSTATUS_INVALID) { - break; - } - - if (m->friend_userstatuschange != nullptr) { - m->friend_userstatuschange(m, i, status, userdata); - } - - set_friend_userstatus(m, i, status); - break; - } - - case PACKET_ID_TYPING: { - if (data_length != 1) { - break; - } - - const bool typing = data[0] != 0; - - set_friend_typing(m, i, typing); - - if (m->friend_typingchange != nullptr) { - m->friend_typingchange(m, i, typing, userdata); - } - - break; - } - - case PACKET_ID_MESSAGE: // fall-through - case PACKET_ID_ACTION: { - if (data_length == 0) { - break; - } - - const uint8_t *message = data; - const uint16_t message_length = data_length; - - /* Make sure the NULL terminator is present. */ - VLA(uint8_t, message_terminated, message_length + 1); - memcpy(message_terminated, message, message_length); - message_terminated[message_length] = 0; - const uint8_t type = packet_id - PACKET_ID_MESSAGE; - - if (m->friend_message != nullptr) { - m->friend_message(m, i, type, message_terminated, message_length, userdata); - } - - break; - } - - case PACKET_ID_INVITE_CONFERENCE: { - if (data_length == 0) { - break; - } - - if (m->conference_invite != nullptr) { - m->conference_invite(m, i, data, data_length, userdata); - } - - break; - } - - case PACKET_ID_FILE_SENDREQUEST: { - const unsigned int head_length = 1 + sizeof(uint32_t) + sizeof(uint64_t) + FILE_ID_LENGTH; - - if (data_length < head_length) { - break; - } - - const uint8_t filenumber = data[0]; - -#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES - - if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { - break; - } - -#endif - - uint64_t filesize; - uint32_t file_type; - const uint16_t filename_length = data_length - head_length; - - if (filename_length > MAX_FILENAME_LENGTH) { - break; - } - - memcpy(&file_type, data + 1, sizeof(file_type)); - file_type = net_ntohl(file_type); - - net_unpack_u64(data + 1 + sizeof(uint32_t), &filesize); - struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; - - if (ft->status != FILESTATUS_NONE) { - break; - } - - ft->status = FILESTATUS_NOT_ACCEPTED; - ft->size = filesize; - ft->transferred = 0; - ft->paused = FILE_PAUSE_NOT; - memcpy(ft->id, data + 1 + sizeof(uint32_t) + sizeof(uint64_t), FILE_ID_LENGTH); - - VLA(uint8_t, filename_terminated, filename_length + 1); - const uint8_t *filename = nullptr; - - if (filename_length > 0) { - /* Force NULL terminate file name. */ - memcpy(filename_terminated, data + head_length, filename_length); - filename_terminated[filename_length] = 0; - filename = filename_terminated; - } - - uint32_t real_filenumber = filenumber; - real_filenumber += 1; - real_filenumber <<= 16; - - if (m->file_sendrequest != nullptr) { - m->file_sendrequest(m, i, real_filenumber, file_type, filesize, filename, filename_length, - userdata); - } - - break; - } - - case PACKET_ID_FILE_CONTROL: { - if (data_length < 3) { - break; - } - - // On the other side, "outbound" is "inbound", i.e. if they send 1, - // that means "inbound" on their side, but we call it "outbound" - // here. - const bool outbound = data[0] == 1; - uint8_t filenumber = data[1]; - const uint8_t control_type = data[2]; - -#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES - - if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { - break; - } - -#endif - - if (handle_filecontrol(m, i, outbound, filenumber, control_type, data + 3, data_length - 3, userdata) == -1) { - // TODO(iphydf): Do something different here? Right now, this - // check is pointless. - break; - } - - break; - } - - case PACKET_ID_FILE_DATA: { - if (data_length < 1) { - break; - } - - uint8_t filenumber = data[0]; - -#if UINT8_MAX >= MAX_CONCURRENT_FILE_PIPES - - if (filenumber >= MAX_CONCURRENT_FILE_PIPES) { - break; - } - -#endif - - struct File_Transfers *ft = &m->friendlist[i].file_receiving[filenumber]; - - if (ft->status != FILESTATUS_TRANSFERRING) { - break; - } - - uint64_t position = ft->transferred; - uint32_t real_filenumber = filenumber; - real_filenumber += 1; - real_filenumber <<= 16; - uint16_t file_data_length = data_length - 1; - const uint8_t *file_data; - - if (file_data_length == 0) { - file_data = nullptr; - } else { - file_data = data + 1; - } - - /* Prevent more data than the filesize from being passed to clients. */ - if ((ft->transferred + file_data_length) > ft->size) { - file_data_length = ft->size - ft->transferred; - } - - if (m->file_filedata != nullptr) { - m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); - } - - ft->transferred += file_data_length; - - if (file_data_length > 0 && (ft->transferred >= ft->size || file_data_length != MAX_FILE_DATA_SIZE)) { - file_data_length = 0; - file_data = nullptr; - position = ft->transferred; - - /* Full file received. */ - if (m->file_filedata != nullptr) { - m->file_filedata(m, i, real_filenumber, position, file_data, file_data_length, userdata); - } - } - - /* Data is zero, filetransfer is over. */ - if (file_data_length == 0) { - ft->status = FILESTATUS_NONE; - } - - break; - } - - case PACKET_ID_MSI: { - if (data_length == 0) { - break; - } - - if (m->msi_packet != nullptr) { - m->msi_packet(m, i, data, data_length, m->msi_packet_userdata); - } - - break; - } - - default: { - handle_custom_lossless_packet(object, i, temp, len, userdata); - break; - } + // TODO(Green-Sky): now all return 0 on error AND success, make errors errors? + case PACKET_ID_OFFLINE: + return m_handle_packet_offline(m, i, data, data_length, userdata); + case PACKET_ID_NICKNAME: + return m_handle_packet_nickname(m, i, data, data_length, userdata); + case PACKET_ID_STATUSMESSAGE: + return m_handle_packet_statusmessage(m, i, data, data_length, userdata); + case PACKET_ID_USERSTATUS: + return m_handle_packet_userstatus(m, i, data, data_length, userdata); + case PACKET_ID_TYPING: + return m_handle_packet_typing(m, i, data, data_length, userdata); + case PACKET_ID_MESSAGE: + return m_handle_packet_message(m, i, data, data_length, MESSAGE_NORMAL, userdata); + case PACKET_ID_ACTION: + return m_handle_packet_message(m, i, data, data_length, MESSAGE_ACTION, userdata); + case PACKET_ID_INVITE_CONFERENCE: + return m_handle_packet_invite_conference(m, i, data, data_length, userdata); + case PACKET_ID_FILE_SENDREQUEST: + return m_handle_packet_file_sendrequest(m, i, data, data_length, userdata); + case PACKET_ID_FILE_CONTROL: + return m_handle_packet_file_control(m, i, data, data_length, userdata); + case PACKET_ID_FILE_DATA: + return m_handle_packet_file_data(m, i, data, data_length, userdata); + case PACKET_ID_MSI: + return m_handle_packet_msi(m, i, data, data_length, userdata); } - return 0; + return m_handle_custom_lossless_packet(object, i, temp, len, userdata); } non_null(1) nullable(2)