diff options
| author | George Hazan <george.hazan@gmail.com> | 2024-02-15 12:18:35 +0300 |
|---|---|---|
| committer | George Hazan <george.hazan@gmail.com> | 2024-02-15 12:18:35 +0300 |
| commit | 31e72718ee54867accf0b739a24adc86f8b7ab54 (patch) | |
| tree | f964c10c5d97d9fe4fd2bd8187c250faedcb0fd7 /protocols/Tox/libtox/src/toxcore/group_pack.c | |
| parent | 282e9c18d9d3b726cce3d2ef0babc88029661cb8 (diff) | |
libtox update
Diffstat (limited to 'protocols/Tox/libtox/src/toxcore/group_pack.c')
| -rw-r--r-- | protocols/Tox/libtox/src/toxcore/group_pack.c | 141 |
1 files changed, 106 insertions, 35 deletions
diff --git a/protocols/Tox/libtox/src/toxcore/group_pack.c b/protocols/Tox/libtox/src/toxcore/group_pack.c index ecdd965610..e3af82c67a 100644 --- a/protocols/Tox/libtox/src/toxcore/group_pack.c +++ b/protocols/Tox/libtox/src/toxcore/group_pack.c @@ -9,20 +9,72 @@ #include "group_pack.h" -#include <assert.h> #include <stdint.h> #include <stdlib.h> #include <string.h> +#include "DHT.h" +#include "attributes.h" #include "bin_pack.h" #include "bin_unpack.h" #include "ccompat.h" +#include "crypto_core.h" +#include "crypto_core_pack.h" +#include "group_common.h" +#include "group_moderation.h" +#include "logger.h" +#include "network.h" #include "util.h" +bool group_privacy_state_from_int(uint8_t value, Group_Privacy_State *out) +{ + switch (value) { + case GI_PUBLIC: { + *out = GI_PUBLIC; + return true; + } + + case GI_PRIVATE: { + *out = GI_PRIVATE; + return true; + } + + default: { + *out = GI_PUBLIC; + return false; + } + } +} + +bool group_voice_state_from_int(uint8_t value, Group_Voice_State *out) +{ + switch (value) { + case GV_ALL: { + *out = GV_ALL; + return true; + } + + case GV_MODS: { + *out = GV_MODS; + return true; + } + + case GV_FOUNDER: { + *out = GV_FOUNDER; + return true; + } + + default: { + *out = GV_ALL; + return false; + } + } +} + non_null() static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 8)) { + if (!bin_unpack_array_fixed(bu, 8, nullptr)) { LOGGER_ERROR(chat->log, "Group state values array malformed"); return false; } @@ -44,8 +96,8 @@ static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu) } chat->connection_state = manually_disconnected ? CS_DISCONNECTED : CS_CONNECTING; - chat->shared_state.privacy_state = (Group_Privacy_State)privacy_state; - chat->shared_state.voice_state = (Group_Voice_State)voice_state; + group_privacy_state_from_int(privacy_state, &chat->shared_state.privacy_state); + group_voice_state_from_int(voice_state, &chat->shared_state.voice_state); // we always load saved groups as private in case the group became private while we were offline. // this will have no detrimental effect if the group is public, as the correct privacy @@ -58,15 +110,23 @@ static bool load_unpack_state_values(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_state_bin(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 5)) { + if (!bin_unpack_array_fixed(bu, 5, nullptr)) { LOGGER_ERROR(chat->log, "Group state binary array malformed"); return false; } - if (!(bin_unpack_bin_fixed(bu, chat->shared_state_sig, SIGNATURE_SIZE) - && bin_unpack_bin_fixed(bu, chat->shared_state.founder_public_key, EXT_PUBLIC_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->shared_state.group_name, chat->shared_state.group_name_len) - && bin_unpack_bin_fixed(bu, chat->shared_state.password, chat->shared_state.password_length) + if (!bin_unpack_bin_fixed(bu, chat->shared_state_sig, SIGNATURE_SIZE)) { + LOGGER_ERROR(chat->log, "Failed to unpack shared state signature"); + return false; + } + + if (!unpack_extended_public_key(&chat->shared_state.founder_public_key, bu)) { + LOGGER_ERROR(chat->log, "Failed to unpack founder public key"); + return false; + } + + if (!(bin_unpack_bin_max(bu, chat->shared_state.group_name, &chat->shared_state.group_name_len, sizeof(chat->shared_state.group_name)) + && bin_unpack_bin_max(bu, chat->shared_state.password, &chat->shared_state.password_length, sizeof(chat->shared_state.password)) && bin_unpack_bin_fixed(bu, chat->shared_state.mod_list_hash, MOD_MODERATION_HASH_SIZE))) { LOGGER_ERROR(chat->log, "Failed to unpack state binary data"); return false; @@ -78,7 +138,7 @@ static bool load_unpack_state_bin(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_topic_info(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 6)) { + if (!bin_unpack_array_fixed(bu, 6, nullptr)) { LOGGER_ERROR(chat->log, "Group topic array malformed"); return false; } @@ -86,7 +146,7 @@ static bool load_unpack_topic_info(GC_Chat *chat, Bin_Unpack *bu) if (!(bin_unpack_u32(bu, &chat->topic_info.version) && bin_unpack_u16(bu, &chat->topic_info.length) && bin_unpack_u16(bu, &chat->topic_info.checksum) - && bin_unpack_bin_fixed(bu, chat->topic_info.topic, chat->topic_info.length) + && bin_unpack_bin_max(bu, chat->topic_info.topic, &chat->topic_info.length, sizeof(chat->topic_info.topic)) && bin_unpack_bin_fixed(bu, chat->topic_info.public_sig_key, SIG_PUBLIC_KEY_SIZE) && bin_unpack_bin_fixed(bu, chat->topic_sig, SIGNATURE_SIZE))) { LOGGER_ERROR(chat->log, "Failed to unpack topic info"); @@ -99,8 +159,9 @@ static bool load_unpack_topic_info(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 2)) { - LOGGER_ERROR(chat->log, "Group mod list array malformed"); + uint32_t actual_size = 0; + if (!bin_unpack_array_fixed(bu, 2, &actual_size)) { + LOGGER_ERROR(chat->log, "Group mod list array malformed: %d != 2", actual_size); return false; } @@ -116,7 +177,7 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) if (chat->moderation.num_mods > MOD_MAX_NUM_MODERATORS) { LOGGER_ERROR(chat->log, "moderation count %u exceeds maximum %u", chat->moderation.num_mods, MOD_MAX_NUM_MODERATORS); - return false; + chat->moderation.num_mods = MOD_MAX_NUM_MODERATORS; } uint8_t *packed_mod_list = (uint8_t *)malloc(chat->moderation.num_mods * MOD_LIST_ENTRY_SIZE); @@ -148,15 +209,15 @@ static bool load_unpack_mod_list(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_keys(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 4)) { + if (!bin_unpack_array_fixed(bu, 4, nullptr)) { LOGGER_ERROR(chat->log, "Group keys array malformed"); return false; } - if (!(bin_unpack_bin_fixed(bu, chat->chat_public_key, EXT_PUBLIC_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->chat_secret_key, EXT_SECRET_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->self_public_key, EXT_PUBLIC_KEY_SIZE) - && bin_unpack_bin_fixed(bu, chat->self_secret_key, EXT_SECRET_KEY_SIZE))) { + if (!(unpack_extended_public_key(&chat->chat_public_key, bu) + && unpack_extended_secret_key(&chat->chat_secret_key, bu) + && unpack_extended_public_key(&chat->self_public_key, bu) + && unpack_extended_secret_key(&chat->self_secret_key, bu))) { LOGGER_ERROR(chat->log, "Failed to unpack keys"); return false; } @@ -167,7 +228,7 @@ static bool load_unpack_keys(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 4)) { + if (!bin_unpack_array_fixed(bu, 4, nullptr)) { LOGGER_ERROR(chat->log, "Group self info array malformed"); return false; } @@ -184,7 +245,10 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) return false; } - assert(self_nick_len <= MAX_GC_NICK_SIZE); + if (self_nick_len > MAX_GC_NICK_SIZE) { + LOGGER_ERROR(chat->log, "self_nick too big (%u bytes), truncating to %d", self_nick_len, MAX_GC_NICK_SIZE); + self_nick_len = MAX_GC_NICK_SIZE; + } if (!bin_unpack_bin_fixed(bu, self_nick, self_nick_len)) { LOGGER_ERROR(chat->log, "Failed to unpack self nick bytes"); @@ -192,16 +256,19 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) } // we have to add ourself before setting self info - if (peer_add(chat, nullptr, chat->self_public_key) != 0) { + if (peer_add(chat, nullptr, chat->self_public_key.enc) != 0) { LOGGER_ERROR(chat->log, "Failed to add self to peer list"); return false; } - assert(chat->numpeers > 0); + if (chat->numpeers == 0) { + LOGGER_ERROR(chat->log, "Failed to unpack self: numpeers should be > 0"); + return false; + } GC_Peer *self = &chat->group[0]; - memcpy(self->gconn.addr.public_key, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); + self->gconn.addr.public_key = chat->self_public_key; memcpy(self->nick, self_nick, self_nick_len); self->nick_length = self_nick_len; self->role = (Group_Role)self_role; @@ -214,7 +281,7 @@ static bool load_unpack_self_info(GC_Chat *chat, Bin_Unpack *bu) non_null() static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 2)) { + if (!bin_unpack_array_fixed(bu, 2, nullptr)) { LOGGER_ERROR(chat->log, "Group saved peers array malformed"); return false; } @@ -256,8 +323,9 @@ static bool load_unpack_saved_peers(GC_Chat *chat, Bin_Unpack *bu) bool gc_load_unpack_group(GC_Chat *chat, Bin_Unpack *bu) { - if (!bin_unpack_array_fixed(bu, 7)) { - LOGGER_ERROR(chat->log, "Group info array malformed"); + uint32_t actual_size; + if (!bin_unpack_array_fixed(bu, 7, &actual_size)) { + LOGGER_ERROR(chat->log, "Group info array malformed: %d != 7", actual_size); return false; } @@ -290,7 +358,7 @@ static void save_pack_state_bin(const GC_Chat *chat, Bin_Pack *bp) bin_pack_array(bp, 5); bin_pack_bin(bp, chat->shared_state_sig, SIGNATURE_SIZE); // 1 - bin_pack_bin(bp, chat->shared_state.founder_public_key, EXT_PUBLIC_KEY_SIZE); // 2 + pack_extended_public_key(&chat->shared_state.founder_public_key, bp); // 2 bin_pack_bin(bp, chat->shared_state.group_name, chat->shared_state.group_name_len); // 3 bin_pack_bin(bp, chat->shared_state.password, chat->shared_state.password_length); // 4 bin_pack_bin(bp, chat->shared_state.mod_list_hash, MOD_MODERATION_HASH_SIZE); // 5 @@ -348,10 +416,10 @@ static void save_pack_keys(const GC_Chat *chat, Bin_Pack *bp) { bin_pack_array(bp, 4); - bin_pack_bin(bp, chat->chat_public_key, EXT_PUBLIC_KEY_SIZE); // 1 - bin_pack_bin(bp, chat->chat_secret_key, EXT_SECRET_KEY_SIZE); // 2 - bin_pack_bin(bp, chat->self_public_key, EXT_PUBLIC_KEY_SIZE); // 3 - bin_pack_bin(bp, chat->self_secret_key, EXT_SECRET_KEY_SIZE); // 4 + pack_extended_public_key(&chat->chat_public_key, bp); // 1 + pack_extended_secret_key(&chat->chat_secret_key, bp); // 2 + pack_extended_public_key(&chat->self_public_key, bp); // 3 + pack_extended_secret_key(&chat->self_secret_key, bp); // 4 } non_null() @@ -359,13 +427,16 @@ static void save_pack_self_info(const GC_Chat *chat, Bin_Pack *bp) { bin_pack_array(bp, 4); - const GC_Peer *self = &chat->group[0]; + GC_Peer *self = &chat->group[0]; - assert(self->nick_length <= MAX_GC_NICK_SIZE); + if (self->nick_length > MAX_GC_NICK_SIZE) { + LOGGER_ERROR(chat->log, "self_nick is too big (%u). Truncating to %d", self->nick_length, MAX_GC_NICK_SIZE); + self->nick_length = MAX_GC_NICK_SIZE; + } bin_pack_u16(bp, self->nick_length); // 1 bin_pack_u08(bp, (uint8_t)self->role); // 2 - bin_pack_u08(bp, (uint8_t)self->status); // 3 + bin_pack_u08(bp, self->status); // 3 bin_pack_bin(bp, self->nick, self->nick_length); // 4 } |
