From 71f73a21e127cf70b597c3d67fc88832ab275b62 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 3 Nov 2026 20:21:16 +0100 Subject: [PATCH] Authorize avatar channels and cancel revoked peer state --- src/chat/group_avatar.c | 22 +++++++++++++++++++++- src/chat/group_avatar.h | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/chat/group_avatar.c b/src/chat/group_avatar.c index 2e5d6ee0b..3bb5825b5 100644 --- a/src/chat/group_avatar.c +++ b/src/chat/group_avatar.c @@ -263,7 +263,7 @@ static struct ga_peer* ga_find(struct group_avatar* ctx, uint64_t group, uint64_ } static int ga_allowed(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t peer) { - if (!member_files_member(inst, group, inst->node_id, 0) || !member_files_member(inst, group, peer, 0)) return 0; + if (!topo_group_chat_allowed(inst, group, peer)) return 0; struct TOPO_GROUP* g = topo_groups_find(inst->topo_groups, group); for (struct ll_entry* e = g && g->senders_list ? g->senders_list->head : NULL; e; e = e->next) { struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; @@ -366,6 +366,7 @@ static void ga_receive(struct ETCP_CONN* conn, struct ll_entry* entry) { uint64_t group, peer; memcpy(&group, entry->dgram + ROUTER_SVC_GROUP_OFF, 8); memcpy(&peer, entry->dgram + ROUTER_SVC_SRC_OFF, 8); struct ga_peer* p = ga_find(ctx, group, peer, 0); if (entry->len == ROUTER_SVC_PAYLOAD_OFF) { + if (!topo_group_chat_allowed(ctx->inst, group, peer)) { group_avatar_revalidate_members(ctx->inst, group); goto out; } if (p) { ga_release(p, 1); ga_release(p, 0); p->requested_at = 0; p->state_pending = 1; ga_schedule(p); } goto out; } @@ -510,6 +511,11 @@ int group_avatar_init(struct UTUN_INSTANCE* inst) { if (etcp_router_bind(inst, ETCP_RT_ID_GROUP_AVATAR, ga_receive)) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: router registration failed"); CC(inst)->group_avatar = NULL; u_free(ctx); return -1; } + if (etcp_router_require_crypto(inst, ETCP_RT_ID_GROUP_AVATAR, ROUTER_FLAG_SIGNED | ROUTER_FLAG_ENCRYPTED) || + etcp_router_set_authorize(inst, ETCP_RT_ID_GROUP_AVATAR, topo_group_chat_allowed)) { + DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: router access policy initialization failed"); + group_avatar_destroy(inst); return -1; + } etcp_router_set_receive_ready(inst, ETCP_RT_ID_GROUP_AVATAR, ga_receive_ready); ctx->timer = uasync_set_timeout(inst->ua, 10000, ctx, ga_tick, "group_avatar"); if (!ctx->timer) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "group avatar: initial timer failed"); group_avatar_destroy(inst); return -1; } @@ -524,6 +530,20 @@ void group_avatar_cancel_group(struct UTUN_INSTANCE* inst, uint64_t group) { while (*link) { struct ga_peer* p = *link; if (p->group != group) link = &p->next; else { *link = p->next; ga_free(p); } } } +void group_avatar_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group) { + struct group_avatar* ctx = ga_context(inst); + if (!ctx || ctx->closing) return; + struct ga_peer** link = &ctx->peers; + while (*link) { + struct ga_peer* p = *link; + if (p->group != group || topo_group_chat_allowed(inst, group, p->peer)) { link = &p->next; continue; } + DEBUG_INFO(DEBUG_CATEGORY_CHAT, "group avatar: revoke group=%llx peer=%llx tx=%d rx=%d pending=%d/%d/%d", + (unsigned long long)group, (unsigned long long)p->peer, p->tx != NULL, p->rx != NULL, + p->state_pending, p->get_pending, p->reply_pending); + *link = p->next; ga_free(p); + } +} + void group_avatar_destroy(struct UTUN_INSTANCE* inst) { struct group_avatar* ctx = ga_context(inst); if (!ctx) return; ctx->closing = 1; if (ctx->timer) uasync_cancel_timeout(inst->ua, ctx->timer); diff --git a/src/chat/group_avatar.h b/src/chat/group_avatar.h index 173d76081..278fb1e35 100644 --- a/src/chat/group_avatar.h +++ b/src/chat/group_avatar.h @@ -39,6 +39,8 @@ void group_avatar_destroy(struct UTUN_INSTANCE* inst); // Отменить сборки/waiters/call_soon канала перед удалением группы; БД и router-сессия остаются у своих владельцев. void group_avatar_cancel_group(struct UTUN_INSTANCE* inst, uint64_t group); +// После commit состава: снять сборки/waiters/call_soon отозванных участников только этого канала; БД сохраняется. +void group_avatar_revalidate_members(struct UTUN_INSTANCE* inst, uint64_t group); // ── Чтение и изменение аватарки ──