|
|
|
@ -35,53 +35,57 @@ void chat_core_update_my_name(const char* name) { |
|
|
|
|
|
|
|
|
|
|
|
uint64_t myid = g_cc.my_node_id; |
|
|
|
uint64_t myid = g_cc.my_node_id; |
|
|
|
sqlite3_stmt* cs = NULL; |
|
|
|
sqlite3_stmt* cs = NULL; |
|
|
|
sqlite3_prepare_v2(g_cc.db, "SELECT channel_id, x25519_pubkey, ed25519_pubkey FROM channels", -1, &cs, NULL); |
|
|
|
sqlite3_prepare_v2(g_cc.db, "SELECT channel_id FROM channels", -1, &cs, NULL); |
|
|
|
if (cs) { |
|
|
|
if (cs) { |
|
|
|
while (sqlite3_step(cs) == SQLITE_ROW) { |
|
|
|
while (sqlite3_step(cs) == SQLITE_ROW) { |
|
|
|
const char* ch = (const char*)sqlite3_column_text(cs, 0); |
|
|
|
const char* ch = (const char*)sqlite3_column_text(cs, 0); |
|
|
|
const uint8_t* ch_x25519 = sqlite3_column_blob(cs, 1); |
|
|
|
if (!ch) continue; |
|
|
|
const uint8_t* ch_ed25519 = sqlite3_column_blob(cs, 2); |
|
|
|
|
|
|
|
if (!ch || !ch_x25519 || !ch_ed25519) continue; |
|
|
|
|
|
|
|
char tbl[80]; peers_table_name(ch, tbl, sizeof(tbl)); |
|
|
|
char tbl[80]; peers_table_name(ch, tbl, sizeof(tbl)); |
|
|
|
char buf[256]; snprintf(buf, sizeof(buf), "SELECT 1 FROM \"%s\" WHERE node_id=?", tbl); |
|
|
|
char buf[256]; snprintf(buf, sizeof(buf), "SELECT update_ts FROM \"%s\" WHERE node_id=?", tbl); |
|
|
|
sqlite3_stmt* ps = NULL; |
|
|
|
sqlite3_stmt* ps = NULL; |
|
|
|
if (sqlite3_prepare_v2(g_cc.db, buf, -1, &ps, NULL) == SQLITE_OK) { |
|
|
|
if (sqlite3_prepare_v2(g_cc.db, buf, -1, &ps, NULL) != SQLITE_OK) continue; |
|
|
|
sqlite3_bind_int64(ps, 1, (sqlite3_int64)myid); |
|
|
|
sqlite3_bind_int64(ps, 1, (sqlite3_int64)myid); |
|
|
|
if (sqlite3_step(ps) == SQLITE_ROW) { |
|
|
|
if (sqlite3_step(ps) != SQLITE_ROW) { sqlite3_finalize(ps); continue; } |
|
|
|
uint8_t join_msg[256]; size_t mlen = 0; |
|
|
|
uint64_t local_uts = (uint64_t)sqlite3_column_int64(ps, 0); |
|
|
|
memcpy(join_msg + mlen, ch_x25519, 32); mlen += 32; |
|
|
|
sqlite3_finalize(ps); |
|
|
|
memcpy(join_msg + mlen, ch_ed25519, 32); mlen += 32; |
|
|
|
|
|
|
|
memcpy(join_msg + mlen, &myid, 8); mlen += 8; |
|
|
|
/* join неизменен при смене имени — читаем существующий join_sig/join_ts */ |
|
|
|
memcpy(join_msg + mlen, g_cc.inst->my_keys.public_key, 32); mlen += 32; |
|
|
|
uint8_t join_sig[64]; uint64_t join_ts = 0; |
|
|
|
uint64_t join_ts = (uint64_t)ntp_time_get_seconds(g_cc.inst); |
|
|
|
if (topo_node_sqlite_member_get_join(g_cc.db, ch, myid, join_sig, &join_ts) != 0) continue; |
|
|
|
memcpy(join_msg + mlen, &join_ts, 8); mlen += 8; |
|
|
|
|
|
|
|
uint8_t new_sig[64]; memset(new_sig, 0, 64); |
|
|
|
char juser[256]; snprintf(juser, sizeof(juser), "{\"name\":\"%s\"}", name); |
|
|
|
EVP_PKEY* pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, |
|
|
|
uint64_t update_ts = (uint64_t)ntp_time_get_seconds(g_cc.inst); |
|
|
|
g_cc.inst->my_ed25519_privkey, 32); |
|
|
|
if (update_ts <= local_uts) update_ts = local_uts + 1; /* гарантируем рост ver */ |
|
|
|
if (pkey) { |
|
|
|
|
|
|
|
EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); |
|
|
|
/* update_sig = sign(join_sig || update_ts || userinfo) ключом мембера */ |
|
|
|
if (mdctx) { |
|
|
|
uint8_t umsg[256 + 64 + 8]; size_t ulen = 0; |
|
|
|
if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) == 1) |
|
|
|
memcpy(umsg + ulen, join_sig, 64); ulen += 64; |
|
|
|
EVP_DigestSign(mdctx, new_sig, &(size_t){64}, join_msg, mlen); |
|
|
|
memcpy(umsg + ulen, &update_ts, 8); ulen += 8; |
|
|
|
EVP_MD_CTX_free(mdctx); |
|
|
|
size_t jl = strlen(juser); |
|
|
|
} |
|
|
|
memcpy(umsg + ulen, juser, jl + 1); ulen += jl + 1; |
|
|
|
EVP_PKEY_free(pkey); |
|
|
|
uint8_t update_sig[64]; memset(update_sig, 0, 64); |
|
|
|
} |
|
|
|
EVP_PKEY* pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, |
|
|
|
char juser[256]; snprintf(juser, sizeof(juser), "{\"name\":\"%s\"}", name); |
|
|
|
g_cc.inst->my_ed25519_privkey, 32); |
|
|
|
int r1 = topo_node_sqlite_member_put(g_cc.db, ch, myid, new_sig, join_ts, NULL, 0, |
|
|
|
if (pkey) { |
|
|
|
g_cc.inst->my_keys.public_key, g_cc.inst->my_ed25519_pubkey, juser, NULL, NULL, NULL, 0); |
|
|
|
EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); |
|
|
|
if (r1 != 0) DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: member_put(my_name) FAILED ch=%s rc=%d", CC_ID, ch, r1); |
|
|
|
if (mdctx) { |
|
|
|
int r2 = member_sync_put(g_cc.inst, ch, myid, g_cc.inst->my_keys.public_key, |
|
|
|
if (EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey) == 1) |
|
|
|
g_cc.inst->my_ed25519_pubkey, new_sig, join_ts, NULL, 0, juser, NULL, 0, NULL, NULL, 0); |
|
|
|
EVP_DigestSign(mdctx, update_sig, &(size_t){64}, umsg, ulen); |
|
|
|
if (r2 != 0) DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: member_sync_put(my_name) FAILED ch=%s rc=%d", CC_ID, ch, r2); |
|
|
|
EVP_MD_CTX_free(mdctx); |
|
|
|
else member_sync_broadcast_one(g_cc.inst, ch, myid); |
|
|
|
|
|
|
|
uint8_t mevt[1 + 64 + 1 + CHAT_MEMBER_DISPLAY_SIZE]; uint8_t cl = (uint8_t)strlen(ch); |
|
|
|
|
|
|
|
mevt[0] = cl; memcpy(mevt + 1, ch, cl); mevt[1 + cl] = 1; |
|
|
|
|
|
|
|
if (chat_core_get_single_member(ch, myid, mevt + 1 + cl + 1) == 0) |
|
|
|
|
|
|
|
chat_event_post(CHAT_EVT_MEMBER_UPDATED, mevt, 1 + cl + 1 + CHAT_MEMBER_DISPLAY_SIZE); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
sqlite3_finalize(ps); |
|
|
|
EVP_PKEY_free(pkey); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int r2 = member_sync_put(g_cc.inst, ch, myid, g_cc.inst->my_keys.public_key, |
|
|
|
|
|
|
|
g_cc.inst->my_ed25519_pubkey, join_sig, join_ts, |
|
|
|
|
|
|
|
update_sig, update_ts, juser, NULL, 0, NULL, NULL, 0); |
|
|
|
|
|
|
|
if (r2 < 0) DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: member_sync_put(my_name) FAILED ch=%s rc=%d", CC_ID, ch, r2); |
|
|
|
|
|
|
|
else if (r2 & MS_APPLY_CHANGED) member_sync_broadcast_one(g_cc.inst, ch, myid); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint8_t mevt[1 + 64 + 1 + CHAT_MEMBER_DISPLAY_SIZE]; uint8_t cl = (uint8_t)strlen(ch); |
|
|
|
|
|
|
|
mevt[0] = cl; memcpy(mevt + 1, ch, cl); mevt[1 + cl] = 1; |
|
|
|
|
|
|
|
if (chat_core_get_single_member(ch, myid, mevt + 1 + cl + 1) == 0) |
|
|
|
|
|
|
|
chat_event_post(CHAT_EVT_MEMBER_UPDATED, mevt, 1 + cl + 1 + CHAT_MEMBER_DISPLAY_SIZE); |
|
|
|
} |
|
|
|
} |
|
|
|
sqlite3_finalize(cs); |
|
|
|
sqlite3_finalize(cs); |
|
|
|
} |
|
|
|
} |
|
|
|
|