Authorize member disclosure separately from recovery requests and clean abandoned versions
This commit is contained in:
1 parent
fcff5c626b
commit
1aa528d352
2 files changed
+31
-5
No files matched your search
+30
-4
@@ -1611,10 +1611,27 @@ static int _member_apply_items(void* ctx, const char* ns, uint64_t from_peer, co
|
||||
}
|
||||
|
||||
static int _member_validate_peer(void* ctx, const char* ns, uint64_t peer) {
|
||||
struct UTUN_INSTANCE* inst = (struct UTUN_INSTANCE*)ctx;
|
||||
sqlite3* db = _db(inst);
|
||||
if (!db) return 0;
|
||||
return topo_node_sqlite_member_in_channel(db, ns, peer);
|
||||
struct UTUN_INSTANCE* inst = ctx;
|
||||
struct ETCP_CONN* conn = inst ? instance_find_conn(inst, peer) : NULL;
|
||||
return conn && conn->initialized && conn->links_up && conn->state != 2 && !conn->close_requested &&
|
||||
topo_group_chat_allowed(inst, chat_channel_id(ns), peer) &&
|
||||
topo_node_sqlite_member_key_allowed(_db(inst), ns, conn->peer_pubkey);
|
||||
}
|
||||
|
||||
/* Разрешение только спросить: канал выбран локально, ключ источника уже связан с его JOIN.
|
||||
* Никаких страниц/хешей в ответ этот режим не выдаёт; источник сам проверяет наш допуск. */
|
||||
static int member_validate_request(void* ctx, const char* ns, uint64_t peer) {
|
||||
struct UTUN_INSTANCE* inst = ctx;
|
||||
struct TOPO_GROUP* group = inst && inst->topo_groups ? topo_groups_find(inst->topo_groups, chat_channel_id(ns)) : NULL;
|
||||
struct ETCP_CONN* conn = inst ? instance_find_conn(inst, peer) : NULL;
|
||||
if (!group || group->group_type != TOPO_GROUP_TYPE_CHAT || group->stopping || strcmp(group->channel_id, ns) ||
|
||||
!conn || !conn->initialized || !conn->links_up || conn->state == 2 || conn->close_requested) return 0;
|
||||
struct member_saved record;
|
||||
int found = member_read_saved(_db(inst), ns, peer, 0, 0, &record);
|
||||
if (found != 1 || record.source || record.malformed || memcmp(record.x, conn->peer_pubkey, 32) ||
|
||||
sc_derive_node_id_from_pubkey(record.x) != peer || _verify_join_sig(_db(inst), ns, &record.rec) != 1) return 0;
|
||||
uint8_t key[32]; enum ms_author_status status = member_sync_author_key(inst, ns, peer, key);
|
||||
return status == MS_AUTHOR_ACTIVE || status == MS_AUTHOR_PENDING;
|
||||
}
|
||||
|
||||
static int member_finish(void* ctx, const char* ns) {
|
||||
@@ -1690,6 +1707,7 @@ static const struct merkle_sync_data_ops g_member_ops = {
|
||||
.get_page = _member_get_page,
|
||||
.apply_items = _member_apply_items,
|
||||
.validate_peer = _member_validate_peer,
|
||||
.validate_request = member_validate_request,
|
||||
.finish = member_finish,
|
||||
.on_result = member_policy_result,
|
||||
.begin_pull = member_begin_pull,
|
||||
@@ -1716,6 +1734,10 @@ static int _rebuild_all_trees(struct UTUN_INSTANCE* inst) {
|
||||
}
|
||||
uint64_t mask = merkle_sync_level_prefix(UINT64_MAX, MT_MAX_LEVEL);
|
||||
char sql[256];
|
||||
snprintf(sql, sizeof(sql), "DELETE FROM \"%s\" WHERE record_state<>0", table);
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, NULL) != SQLITE_OK) { rc = SQLITE_ERROR; break; }
|
||||
if (sqlite3_changes(db)) DEBUG_INFO(DEBUG_CATEGORY_MEMBER_SYNC, "member receive abandoned versions removed ch=%s rows=%d",
|
||||
ns, sqlite3_changes(db));
|
||||
snprintf(sql, sizeof(sql), "SELECT DISTINCT (node_id & %lld) FROM \"%s\" WHERE record_state=0 AND source=0", (long long)mask, table);
|
||||
sqlite3_stmt* leaves = NULL;
|
||||
int lr = sqlite3_prepare_v2(db, sql, -1, &leaves, NULL);
|
||||
@@ -1829,6 +1851,10 @@ void member_sync_destroy(struct UTUN_INSTANCE* inst) {
|
||||
|
||||
int member_sync_start(struct UTUN_INSTANCE* inst, uint64_t peer,
|
||||
const char* ch_id, merkle_sync_done_cb done_cb, void* arg) {
|
||||
if (!_member_validate_peer(inst, ch_id, peer) && !member_validate_request(inst, ch_id, peer)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEMBER_SYNC, "member start denied ch=%s peer=%016llx", ch_id ? ch_id : "-", (unsigned long long)peer);
|
||||
return -1;
|
||||
}
|
||||
if (member_sync_verify_and_purge(inst, ch_id) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: start rejected after purge failure ns=%s peer=%016llx",
|
||||
MS_ID, ch_id ? ch_id : "-", (unsigned long long)peer); return -1;
|
||||
|
||||
@@ -25,7 +25,7 @@ static void media_test_group(struct UTUN_INSTANCE* inst, uint64_t id, const uint
|
||||
if (queue_data_put_with_index(inst->topo_groups->group_list, &g->ll)) abort();
|
||||
}
|
||||
char sql[512];
|
||||
snprintf(sql, sizeof(sql), "CREATE TABLE IF NOT EXISTS peers_%llu(node_id INTEGER PRIMARY KEY,source INTEGER DEFAULT 0,"
|
||||
snprintf(sql, sizeof(sql), "CREATE TABLE IF NOT EXISTS peers_%llu(node_id INTEGER PRIMARY KEY,record_state INTEGER DEFAULT 0,source INTEGER DEFAULT 0,"
|
||||
"deleted INTEGER DEFAULT 0,admitted INTEGER DEFAULT 1,node_type INTEGER DEFAULT 0,adm_tags TEXT DEFAULT '{}')",
|
||||
(unsigned long long)id);
|
||||
if (sqlite3_exec(inst->topo_sqlite_db, sql, NULL, NULL, NULL) != SQLITE_OK) abort();
|
||||
|
||||
Reference in new issue
Block a user