fix(chat): verify incoming JOIN profiles before local insertion
This commit is contained in:
1 parent
054ade0dcd
commit
ce3287ac94
5 files changed
+89
-37
No files matched your search
+27
-2
@@ -7,10 +7,11 @@
|
||||
// Задача 2 (интеграция): два инстанса A(инвайтер) и C(connection) — регистрация join-ключа
|
||||
// через etcp_router, после сходимости BGP lookup_inviter(C) == A.node_id.
|
||||
//
|
||||
// chat_core/chat_sync (глобальные синглтоны) НЕ используются: конфиг без секции [chatserver],
|
||||
// Сервис chat_core/chat_sync не запускается: конфиг без секции [chatserver],
|
||||
// member_sync/chat_join инициализируются вручную.
|
||||
|
||||
#include "chat_join.h"
|
||||
#include "chat_event.h"
|
||||
#include "../routing_layer/etcp_router.h"
|
||||
#include "../routing_layer/route_crypto.h"
|
||||
#include "../transport_layer/etcp_api.h"
|
||||
@@ -31,6 +32,7 @@
|
||||
#include "test_net.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <assert.h>
|
||||
#define OPENSSL_API_COMPAT 0x10100000L
|
||||
#include <openssl/evp.h>
|
||||
#include <stdio.h>
|
||||
@@ -58,6 +60,14 @@ static char g_tdir[256] = "/tmp/utun_cj_XXXXXX";
|
||||
static char g_cfg[MAX_NODES][256];
|
||||
static char g_db_dir[MAX_NODES][320];
|
||||
static uint64_t g_group_id = 0;
|
||||
static unsigned join_results;
|
||||
static void check_join_event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int len) {
|
||||
(void)inst;
|
||||
if (type != CHAT_EVT_CONNECT_RESULT) return;
|
||||
uint64_t request; int32_t result;
|
||||
assert(len == 28); memcpy(&request, data + 20, 8); memcpy(&result, data + 8, 4);
|
||||
assert(request == 0 && result == 0); join_results++;
|
||||
}
|
||||
|
||||
/* ── крипто-хелперы ── */
|
||||
|
||||
@@ -415,6 +425,7 @@ static void t_process_request(void) {
|
||||
|
||||
/* 1. валидный join_sig → мембер добавлен, signed_by=self, подпись валидна */
|
||||
TEST("process_request: valid join_sig accepted"); {
|
||||
chat_event_set_handler(inst, check_join_event);
|
||||
struct joiner j; make_joiner(&j, ch_x_pub, ch_ed_pub);
|
||||
uint8_t buf[512]; size_t len = 0;
|
||||
serialize_member(j.node_id, j.x_pub, j.ed_pub, j.join_sig, j.join_ts, buf, sizeof(buf), &len);
|
||||
@@ -427,8 +438,22 @@ static void t_process_request(void) {
|
||||
rec.x25519 = j.x_pub; rec.signature = sig; rec.signed_by = sb;
|
||||
int vs = (gs == 0) ? member_sync_verify_signature(db, CH_COMP, &rec) : -99;
|
||||
|
||||
if (in_ch == 1 && gs == 0 && sb == inst->node_id && vs == 1) OK();
|
||||
if (in_ch == 1 && gs == 0 && sb == inst->node_id && vs == 1 && join_results == 1) OK();
|
||||
else FAIL("in_ch=%d gs=%d sb=%016llx vs=%d", in_ch, gs, (unsigned long long)sb, vs);
|
||||
chat_event_set_handler(inst, NULL);
|
||||
}
|
||||
|
||||
TEST("process_request: signed profile accepted"); {
|
||||
struct joiner j; make_joiner(&j, ch_x_pub, ch_ed_pub);
|
||||
uint8_t update[64], message[MS_USERINFO_MAX + 73], buf[MS_USERINFO_MAX + 256]; size_t len;
|
||||
struct join_member_data m = {.node_id = j.node_id, .x25519 = j.x_pub, .ed25519 = j.ed_pub,
|
||||
.join_sig = j.join_sig, .join_ts = j.join_ts, .update_sig = update, .update_ts = 1};
|
||||
strcpy(m.userinfo, "{\"name\":\"signed profile\"}");
|
||||
int bytes = member_sync_build_update_msg(j.join_sig, m.update_ts, m.userinfo, message, sizeof(message));
|
||||
assert(bytes > 0 && sc_ed25519_sign(j.ed_priv, message, (size_t)bytes, update) == SC_OK);
|
||||
assert(!chat_join_serialize_member(&m, buf, sizeof(buf), &len));
|
||||
chat_join_process_request(inst, group_id, j.node_id, JOIN_KEY, buf, len);
|
||||
if (topo_node_sqlite_member_in_channel(db, CH_COMP, j.node_id)) OK(); else FAIL();
|
||||
}
|
||||
|
||||
/* 2. невалидный join_sig → отклонён */
|
||||
|
||||
Reference in new issue
Block a user