From 794d7b70f3a353da6bb135f24f09cae4299b1699 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 1 Oct 2026 14:27:54 +0300 Subject: [PATCH] Authorize DM custody by signed group role instead of NAT type --- src/dm/dm_mailbox.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/dm/dm_mailbox.c b/src/dm/dm_mailbox.c index 87658f27..d53b70a6 100644 --- a/src/dm/dm_mailbox.c +++ b/src/dm/dm_mailbox.c @@ -12,6 +12,7 @@ #include "../../lib/mem.h" #include "../../lib/ll_queue.h" #include "../../lib/debug_config.h" +#include "../../lib/json_flat.h" #include #include #include @@ -33,9 +34,23 @@ static int mb_scope(struct dm_mb_state* mb, uint64_t gid, uint64_t super, uint64 if (!gid) return 0; char ch[64]; snprintf(ch, sizeof(ch), "%llu", (unsigned long long)gid); - return topo_node_sqlite_member_in_channel(mb->db, ch, super) && - topo_node_sqlite_get_node_type(mb->db, ch, super) == 4 && - topo_node_sqlite_member_in_channel(mb->db, ch, a) && + char sql[256]; + snprintf(sql, sizeof(sql), "SELECT adm_tags FROM \"peers_%s\" WHERE node_id=? AND deleted=0", ch); + sqlite3_stmt* st = NULL; + if (sqlite3_prepare_v2(mb->db, sql, -1, &st, NULL) != SQLITE_OK) { + DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: role query failed group=%llu: %s", MB_ID, + (unsigned long long)gid, sqlite3_errmsg(mb->db)); + return 0; + } + sqlite3_bind_int64(st, 1, (sqlite3_int64)super); + int allowed = 0; + char role[16]; + if (sqlite3_step(st) == SQLITE_ROW) { + const char* tags = (const char*)sqlite3_column_text(st, 0); + allowed = tags && json_flat_get(tags, "supernode", role, sizeof(role)) == 0 && !strcmp(role, "yes"); + } + sqlite3_finalize(st); + return allowed && topo_node_sqlite_member_in_channel(mb->db, ch, a) && topo_node_sqlite_member_in_channel(mb->db, ch, b); } @@ -357,7 +372,7 @@ static int mb_to_supernodes(struct dm_mb_state* mb, uint64_t recipient, uint64_t snprintf(ch, sizeof(ch), "%llu", (unsigned long long)ids[i]); if (!topo_node_sqlite_member_in_channel(mb->db, ch, author) || !topo_node_sqlite_member_in_channel(mb->db, ch, recipient)) continue; - snprintf(sql, sizeof(sql), "SELECT node_id FROM \"peers_%s\" WHERE node_type=4 AND deleted=0 ORDER BY node_id", ch); + snprintf(sql, sizeof(sql), "SELECT node_id,adm_tags FROM \"peers_%s\" WHERE deleted=0 ORDER BY node_id", ch); sqlite3_stmt* st = NULL; if (sqlite3_prepare_v2(mb->db, sql, -1, &st, NULL) != SQLITE_OK) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "%s: supernode query failed: %s", MB_ID, sqlite3_errmsg(mb->db)); @@ -366,6 +381,9 @@ static int mb_to_supernodes(struct dm_mb_state* mb, uint64_t recipient, uint64_t int rc; while ((rc = sqlite3_step(st)) == SQLITE_ROW) { uint64_t node = (uint64_t)sqlite3_column_int64(st, 0); + const char* tags = (const char*)sqlite3_column_text(st, 1); + char role[16]; + if (!tags || json_flat_get(tags, "supernode", role, sizeof(role)) != 0 || strcmp(role, "yes")) continue; if (node == mb->inst->node_id || node == recipient || node == author) continue; struct ETCP_ROUTER_PATH path = etcp_router_get_path(mb->inst, ids[i], node, ETCP_RT_ID_DM_MAILBOX); if (!path.next_hop_node_id) continue;