Browse Source

chat_sync: node_name теперь в пакетах — CHANNEL_INFO_RESP/JOIN/PEER_UPSERT передают имя, верификация использует имя из пакета (не из БД)

topo_upd
Evgeny 3 months ago
parent
commit
0d5a72c40e
  1. 82
      tools/chatgui/transport/chat_sync.c

82
tools/chatgui/transport/chat_sync.c

@ -813,6 +813,9 @@ static void cs_handle_channel_info_req(struct chat_sync* cs, uint64_t peer,
memcpy(buf + boff, ed_pub, 32); boff += 32;
memcpy(buf + boff, ch_sig, 64); boff += 64;
memcpy(buf + boff, my_join_sig, 64); boff += 64;
{ const char* iname = cs->inst->name[0] ? cs->inst->name : "";
uint8_t il = (uint8_t)strlen(iname);
buf[boff++] = il; memcpy(buf + boff, iname, il); boff += il; }
cs_send(cs, ch_id, peer, buf, boff);
}
@ -822,7 +825,8 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
const char* ch_id, const uint8_t* pl, size_t len) {
if (cs->info_req_timer) { uasync_cancel_timeout(cs->inst->ua, cs->info_req_timer); cs->info_req_timer = NULL; }
if (len < 1) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP too short len=%zu peer=%016llx", CS_ID, len, (unsigned long long)peer); return; }
uint8_t nl = pl[0]; if (1 + nl + 8 + 1 + 32 + 32 + 64 + 64 > len) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP truncated len=%zu need=%d", CS_ID, len, 1 + nl + 8 + 1 + 32 + 32 + 64 + 64); return; }
uint8_t nl = pl[0];
if (1 + nl + 8 + 1 + 32 + 32 + 64 + 64 + 1 > len) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP truncated len=%zu min=%d", CS_ID, len, 1 + nl + 8 + 1 + 32 + 32 + 64 + 64 + 1); return; }
const uint8_t* p = pl + 1;
char name[128]; memcpy(name, p, nl); name[nl] = '\0'; p += nl;
uint64_t owner; memcpy(&owner, p, 8); p += 8;
@ -830,7 +834,10 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
const uint8_t* x25519 = p; p += 32;
const uint8_t* ed_pub = p; p += 32;
const uint8_t* ch_sig = p; p += 64;
const uint8_t* inviter_join_sig = p;
const uint8_t* inviter_join_sig = p; p += 64;
uint8_t inv_name_len = *p++;
char inv_name[128] = "";
if (p + inv_name_len <= pl + len) { memcpy(inv_name, p, inv_name_len); inv_name[inv_name_len] = '\0'; }
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "%s: CHANNEL_INFO_RESP from peer=%016llx owner=%016llx ch_x25519=%016llx ch_ed=%016llx name=%s",
CS_ID, (unsigned long long)peer, (unsigned long long)owner,
@ -853,7 +860,7 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
ch_id, name, (int)is_dm, owner, x25519, NULL, ed_pub, NULL, ch_sig);
chat_core_ensure_channel_ready(ch_id);
/* verify inviter's join_sig using ETCP-authenticated keys */
/* verify inviter's join_sig AND save node info using ETCP-authenticated keys */
{ struct ETCP_CONN* inv_conn = cs_find_conn_for_node(cs->inst, peer);
if (!inv_conn) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP no ETCP conn for inviter peer=%016llx", CS_ID, (unsigned long long)peer);
@ -865,13 +872,24 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
ilen += snprintf((char*)ivmsg + ilen, sizeof(ivmsg) - ilen, "%s", ch_id) + 1;
memcpy(ivmsg + ilen, &peer, 8); ilen += 8;
memcpy(ivmsg + ilen, inv_x25519, 32); ilen += 32;
{ char nnm[64] = ""; _get_node_name(cs->inst->topo_groups->topo_sqlite_db, peer, nnm, sizeof(nnm));
size_t nl = strlen(nnm); memcpy(ivmsg + ilen, nnm, nl); ilen += nl; ivmsg[ilen++] = '\0';
{ const char* nm = inv_name[0] ? inv_name : "";
size_t nl2 = strlen(nm); memcpy(ivmsg + ilen, nm, nl2); ilen += nl2; ivmsg[ilen++] = '\0';
if (cs_ed25519_verify(inv_ed, ivmsg, ilen, inviter_join_sig) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP invalid inviter_join_sig peer=%016llx x25519=%016llx inv_ed=%016llx name=%s",
CS_ID, (unsigned long long)peer, *(const uint64_t*)inv_x25519, *(const uint64_t*)inv_ed, nnm);
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_INFO_RESP invalid inviter_join_sig peer=%016llx x25519=%016llx inv_ed=%016llx inv_name=%s",
CS_ID, (unsigned long long)peer, *(const uint64_t*)inv_x25519, *(const uint64_t*)inv_ed, nm);
}
}
/* save inviter node_info to local DB */
sqlite3* vdb = cs->inst->topo_groups->topo_sqlite_db;
if (vdb && inv_name[0]) {
sqlite3_stmt* ns = NULL;
sqlite3_prepare_v2(vdb, "INSERT OR REPLACE INTO nodes(node_id,name,x25519_pubkey,ed25519_pubkey) VALUES(?,?,?,?)", -1, &ns, NULL);
if (ns) { sqlite3_bind_int64(ns, 1, (sqlite3_int64)peer);
sqlite3_bind_text(ns, 2, inv_name, -1, SQLITE_STATIC);
sqlite3_bind_blob(ns, 3, inv_x25519, 32, SQLITE_STATIC);
sqlite3_bind_blob(ns, 4, inv_ed, 32, SQLITE_STATIC);
sqlite3_step(ns); sqlite3_finalize(ns); }
}
}
/* save inviter as node and member */
@ -900,6 +918,9 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
memcpy(jbuf + joff, my_x25519, 32); joff += 32;
memcpy(jbuf + joff, cs->inst->my_ed25519_pubkey, 32); joff += 32;
memcpy(jbuf + joff, join_sig, 64); joff += 64;
{ const char* nm = cs->inst->name[0] ? cs->inst->name : "";
uint8_t nml = (uint8_t)strlen(nm);
jbuf[joff++] = nml; memcpy(jbuf + joff, nm, nml); joff += nml; }
/* add local addresses */
uint8_t addr_cnt = 0; size_t ac_pos = joff;
jbuf[joff++] = 0;
@ -942,12 +963,15 @@ static void cs_handle_channel_info_resp(struct chat_sync* cs, uint64_t peer,
static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
const char* ch_id, const uint8_t* pl, size_t len) {
if (len < 8 + 32 + 32 + 64 + 1) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_JOIN too short len=%zu peer=%016llx", CS_ID, len, (unsigned long long)peer); return; }
if (len < 8 + 32 + 32 + 64 + 1 + 1) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: CHANNEL_JOIN too short len=%zu peer=%016llx", CS_ID, len, (unsigned long long)peer); return; }
const uint8_t* p = pl;
uint64_t node_id; memcpy(&node_id, p, 8); p += 8;
const uint8_t* x25519 = p; p += 32;
const uint8_t* ed_pub = p; p += 32;
const uint8_t* join_sig = p; p += 64;
uint8_t name_len = *p++;
char joiner_name[128] = "";
if (p + name_len <= pl + len) { memcpy(joiner_name, p, name_len); joiner_name[name_len] = '\0'; p += name_len; }
uint8_t addr_cnt = *p++;
/* verify join_sig */
@ -955,17 +979,27 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
vlen += snprintf((char*)vmsg + vlen, sizeof(vmsg) - vlen, "%s", ch_id) + 1;
memcpy(vmsg + vlen, &node_id, 8); vlen += 8;
memcpy(vmsg + vlen, x25519, 32); vlen += 32;
{ sqlite3* tdb = cs->inst->topo_groups->topo_sqlite_db; char nnm[64] = ""; _get_node_name(tdb, node_id, nnm, sizeof(nnm));
size_t nl = strlen(nnm); memcpy(vmsg + vlen, nnm, nl); vlen += nl; vmsg[vlen++] = '\0'; }
{ const char* nm = joiner_name[0] ? joiner_name : "";
size_t nl = strlen(nm); memcpy(vmsg + vlen, nm, nl); vlen += nl; vmsg[vlen++] = '\0'; }
if (cs_ed25519_verify(ed_pub, vmsg, vlen, join_sig) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: JOIN invalid sig node=0x%016llx ch=%s — signed(node=%016llx x25519=%016llx ed=%016llx)", CS_ID,
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: JOIN invalid sig node=0x%016llx ch=%s — signed(node=%016llx x25519=%016llx ed=%016llx name=%s)", CS_ID,
(unsigned long long)node_id, ch_id,
(unsigned long long)node_id, *(const uint64_t*)x25519, *(const uint64_t*)ed_pub);
(unsigned long long)node_id, *(const uint64_t*)x25519, *(const uint64_t*)ed_pub, joiner_name);
return;
}
sqlite3* db = cs->inst->topo_groups->topo_sqlite_db;
topo_node_sqlite_member_put(db, ch_id, node_id, join_sig, NULL);
/* save joiner node_info to local DB */
if (db && joiner_name[0]) {
sqlite3_stmt* ns = NULL;
sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO nodes(node_id,name,x25519_pubkey,ed25519_pubkey) VALUES(?,?,?,?)", -1, &ns, NULL);
if (ns) { sqlite3_bind_int64(ns, 1, (sqlite3_int64)node_id);
sqlite3_bind_text(ns, 2, joiner_name, -1, SQLITE_STATIC);
sqlite3_bind_blob(ns, 3, x25519, 32, SQLITE_STATIC);
sqlite3_bind_blob(ns, 4, ed_pub, 32, SQLITE_STATIC);
sqlite3_step(ns); sqlite3_finalize(ns); }
}
/* save/update node addresses */
for (uint8_t i = 0; i < addr_cnt && p + 1 <= pl + len; i++) {
@ -1010,10 +1044,12 @@ static void cs_handle_channel_join(struct chat_sync* cs, uint64_t peer,
memcpy(ubuf + uoff, x25519, 32); uoff += 32;
memcpy(ubuf + uoff, ed_pub, 32); uoff += 32;
memcpy(ubuf + uoff, join_sig, 64); uoff += 64;
ubuf[uoff++] = name_len;
memcpy(ubuf + uoff, joiner_name, name_len); uoff += name_len;
ubuf[uoff++] = addr_cnt;
size_t addr_data_sz = (size_t)(p - (pl + 8 + 32 + 32 + 64 + 1));
size_t addr_data_sz = (size_t)(p - (pl + 8 + 32 + 32 + 64 + 1 + name_len + 1));
if (uoff + addr_data_sz <= sizeof(ubuf)) {
memcpy(ubuf + uoff, pl + 8 + 32 + 32 + 64 + 1, addr_data_sz);
memcpy(ubuf + uoff, pl + 8 + 32 + 32 + 64 + 1 + name_len + 1, addr_data_sz);
uoff += addr_data_sz;
}
cs_propagate(cs, ch_id, peer, ubuf, uoff);
@ -1100,12 +1136,15 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer,
static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
const char* ch_id, const uint8_t* pl, size_t len) {
if (len < 8 + 32 + 32 + 64 + 1) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: PEER_UPSERT too short len=%zu", CS_ID, len); return; }
if (len < 8 + 32 + 32 + 64 + 1 + 1 + 1) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTIVITY, "%s: PEER_UPSERT too short len=%zu", CS_ID, len); return; }
const uint8_t* p = pl;
uint64_t node_id; memcpy(&node_id, p, 8); p += 8;
const uint8_t* x25519 = p; p += 32;
const uint8_t* ed_pub = p; p += 32;
const uint8_t* join_sig = p; p += 64;
uint8_t name_len = *p++;
char peer_name[128] = "";
if (p + name_len <= pl + len) { memcpy(peer_name, p, name_len); peer_name[name_len] = '\0'; p += name_len; }
uint8_t ac = *p++;
/* verify join_sig */
@ -1113,8 +1152,8 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
vlen += snprintf((char*)vmsg + vlen, sizeof(vmsg) - vlen, "%s", ch_id) + 1;
memcpy(vmsg + vlen, &node_id, 8); vlen += 8;
memcpy(vmsg + vlen, x25519, 32); vlen += 32;
{ sqlite3* tdb = cs->inst->topo_groups->topo_sqlite_db; char nnm[64] = ""; _get_node_name(tdb, node_id, nnm, sizeof(nnm));
size_t nl = strlen(nnm); memcpy(vmsg + vlen, nnm, nl); vlen += nl; vmsg[vlen++] = '\0'; }
{ const char* nm = peer_name[0] ? peer_name : "";
size_t nl = strlen(nm); memcpy(vmsg + vlen, nm, nl); vlen += nl; vmsg[vlen++] = '\0'; }
if (cs_ed25519_verify(ed_pub, vmsg, vlen, join_sig) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTIVITY, "%s: PEER_UPSERT invalid sig node=0x%016llx", CS_ID,
(unsigned long long)node_id);
@ -1124,6 +1163,15 @@ static void cs_handle_peer_upsert(struct chat_sync* cs, uint64_t peer,
sqlite3* db = cs->inst->topo_groups->topo_sqlite_db;
topo_node_sqlite_member_put(db, ch_id, node_id, join_sig, NULL);
if (db && peer_name[0]) {
sqlite3_stmt* ns = NULL;
sqlite3_prepare_v2(db, "INSERT OR REPLACE INTO nodes(node_id,name,x25519_pubkey,ed25519_pubkey) VALUES(?,?,?,?)", -1, &ns, NULL);
if (ns) { sqlite3_bind_int64(ns, 1, (sqlite3_int64)node_id);
sqlite3_bind_text(ns, 2, peer_name, -1, SQLITE_STATIC);
sqlite3_bind_blob(ns, 3, x25519, 32, SQLITE_STATIC);
sqlite3_bind_blob(ns, 4, ed_pub, 32, SQLITE_STATIC);
sqlite3_step(ns); sqlite3_finalize(ns); }
}
for (uint8_t i = 0; i < ac; i++) {
if (p + 1 > pl + len) break;

Loading…
Cancel
Save