Browse Source

Read complete signed profiles and escape initial display names

master
evgeny 6 days ago
parent
commit
9279ded7f3
  1. 4
      src/chat/chat_channel.c
  2. 3
      src/chat/chat_core.h
  3. 32
      src/chat/chat_profile.c

4
src/chat/chat_channel.c

@ -123,14 +123,12 @@ void chat_core_create_channel(struct UTUN_INSTANCE* inst, struct chat_channel_cr
myid, inst->my_keys.public_key,
join_ts, inst->my_ed25519_privkey, join_sig);
char juser3[256]; snprintf(juser3, sizeof(juser3), "{\"name\":\"%s\"}",
inst->name[0] ? inst->name : "");
/* корень дерева приглашений: подписан ключом группы (канальный ed25519) */
uint8_t root_sig[64]; memset(root_sig, 0, 64);
member_sync_sign_pubkey(req->ed25519_privkey, inst->my_keys.public_key, root_sig);
int mrc = member_sync_put(inst, req->channel_id, myid,
inst->my_keys.public_key, inst->my_ed25519_pubkey,
join_sig, join_ts, NULL, 0, juser3, NULL, NULL, 0, 0, root_sig);
join_sig, join_ts, NULL, 0, "{}", NULL, NULL, 0, 0, root_sig);
if (mrc < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: member_sync_put(self) FAILED ch=%s rc=%d",
CC_ID, req->channel_id, mrc);

3
src/chat/chat_core.h

@ -241,6 +241,9 @@ int chat_core_get_node_name(struct UTUN_INSTANCE* inst, uint64_t node_id, char*
/* Аватарка лежит в avatars/<sha256>.png внутри дерева своего UID/канала. server=0 удаляет ссылку. */
int chat_core_set_my_avatar(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t server, const char* file);
int chat_core_name_userinfo(const char* name, char* out, size_t capacity);
int chat_core_get_my_profile(struct UTUN_INSTANCE* inst, const char* channel, char* out, size_t capacity,
uint8_t signature[64], uint64_t* timestamp);
struct chat_avatar_req {
struct UTUN_INSTANCE* inst;
uint64_t id, group, server;

32
src/chat/chat_profile.c

@ -85,6 +85,38 @@ static int profile_copy_pair(const char* key, const char* value, void* arg) {
return profile_pair(p, key, value);
}
int chat_core_name_userinfo(const char* name, char* out, size_t capacity) {
struct profile_json p = { .text = "{", .used = 1 };
if (!name || !out || profile_pair(&p, "name", name) < 0 || p.used + 2 > capacity || p.used >= MS_USERINFO_MAX) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "profile: cannot encode display name capacity=%zu", capacity); return -1;
}
p.text[p.used++] = '}'; p.text[p.used] = 0; memcpy(out, p.text, p.used + 1); return 0;
}
int chat_core_get_my_profile(struct UTUN_INSTANCE* inst, const char* channel, char* out, size_t capacity,
uint8_t signature[64], uint64_t* timestamp) {
struct chat_core_ctx* cc = CC(inst);
if (!cc || !cc->db || !channel || !out || !signature || !timestamp) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "profile: invalid read request"); return -1;
}
char table[80], sql[256]; peers_table_name(channel, table, sizeof(table));
snprintf(sql, sizeof(sql), "SELECT userinfo,update_sig,update_ts FROM \"%s\" WHERE node_id=?", table);
sqlite3_stmt* st = NULL; int result = -1;
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) == SQLITE_OK) {
sqlite3_bind_int64(st, 1, (sqlite3_int64)cc->my_node_id);
if (sqlite3_step(st) == SQLITE_ROW) {
const char* json = (const char*)sqlite3_column_text(st, 0); size_t size = json ? strlen(json) : 0;
if (json && size <= MS_USERINFO_MAX && size < capacity && sqlite3_column_bytes(st, 1) == 64 && sqlite3_column_int64(st, 2) > 0) {
memcpy(out, json, size + 1); memcpy(signature, sqlite3_column_blob(st, 1), 64);
*timestamp = (uint64_t)sqlite3_column_int64(st, 2); result = 0;
}
}
sqlite3_finalize(st);
}
if (result) DEBUG_WARN(DEBUG_CATEGORY_CHAT, "profile: signed local profile unavailable channel=%s capacity=%zu", channel, capacity);
return result;
}
static int profile_update_channel(struct UTUN_INSTANCE* inst, const char* ch, int avatar, uint64_t server, const char* file) {
struct chat_core_ctx* cc = CC(inst);
if (!cc || !cc->initialized || !cc->db) {

Loading…
Cancel
Save