From 8029b6e3f5d4bf5b2a8c7ca08e2bd0bb785ffc09 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 6 Oct 2026 12:25:21 +0200 Subject: [PATCH] Extend signed member profiles to 1024 bytes --- src/chat/member_sync.c | 22 +++++++++++----------- src/chat/member_sync.h | 1 + 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/chat/member_sync.c b/src/chat/member_sync.c index 09c4e988..dadcffc6 100644 --- a/src/chat/member_sync.c +++ b/src/chat/member_sync.c @@ -63,7 +63,7 @@ static int _compute_member_hash(uint64_t node_id, const uint8_t* x25519, const u const uint8_t* join_sig, uint64_t join_ts, const uint8_t* update_sig, uint64_t update_ts, const char* userinfo, const char* adm_tags, const uint8_t* adm_tags_sig, uint64_t signed_by, const uint8_t* signature, uint8_t hash_out[MT_HASH_SIZE]) { - uint8_t data[MS_ADM_TAGS_MAX + 1024]; + uint8_t data[MS_ADM_TAGS_MAX + MS_USERINFO_MAX + 512]; size_t off = 0; member_write64(data + off, node_id); off += 8; memcpy(data + off, x25519, 32); off += 32; @@ -73,11 +73,11 @@ static int _compute_member_hash(uint64_t node_id, const uint8_t* x25519, const u if (update_sig) memcpy(data + off, update_sig, 64); else memset(data + off, 0, 64); off += 64; member_write64(data + off, update_ts); off += 8; size_t ul = userinfo ? strlen(userinfo) : 0, atl = adm_tags ? strlen(adm_tags) : 0; - if (ul > 255 || atl > MS_ADM_TAGS_MAX) { + if (ul > MS_USERINFO_MAX || atl > MS_ADM_TAGS_MAX) { DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: member strings exceed wire limits node=%016llx", MS_ID, (unsigned long long)node_id); return -1; } - data[off++] = (uint8_t)ul; + data[off++] = (uint8_t)(ul >> 8); data[off++] = (uint8_t)ul; if (ul) { memcpy(data + off, userinfo, ul); off += ul; } data[off++] = (uint8_t)(atl >> 8); data[off++] = (uint8_t)atl; if (atl) { memcpy(data + off, adm_tags, atl); off += atl; } @@ -251,15 +251,15 @@ static int _member_get_page(void* ctx, const char* ns, uint64_t prefix, int afte if (src != 0) continue; if (!member_blob(stmt, 1, 32, 0) || !member_blob(stmt, 2, 32, 0) || !member_blob(stmt, 3, 64, 1) || !member_blob(stmt, 5, 64, 1) || !member_blob(stmt, 9, 64, 1) || !member_blob(stmt, 11, 64, 1) - || (nm && strlen(nm) > 255) || (atags && strlen(atags) > MS_ADM_TAGS_MAX)) { + || (nm && strlen(nm) > MS_USERINFO_MAX) || (atags && strlen(atags) > MS_ADM_TAGS_MAX)) { DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: invalid page record ns=%s node=%016llx", MS_ID, ns, (unsigned long long)nid); sqlite3_finalize(stmt); return -1; } - uint8_t nl = nm ? (uint8_t)strnlen(nm, 255) : 0; + size_t nl = nm ? strlen(nm) : 0; size_t atl = atags ? strlen(atags) : 0; uint8_t flags = (sig && jts) ? PEERS_FLAG_HAS_JOIN : 0; - size_t need = 8 + 32 + 32 + 1 + (flags ? 72ULL : 0ULL) + 64 + 8 + 1 + (size_t)nl + 2 + atl + 64 + 8 + 64; + size_t need = 8 + 32 + 32 + 1 + (flags ? 72ULL : 0ULL) + 64 + 8 + 2 + nl + 2 + atl + 64 + 8 + 64; if (off + need > *len) { if (!cnt) { DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: record exceeds page capacity ns=%s", MS_ID, ns); sqlite3_finalize(stmt); return -1; } *more = 1; @@ -280,7 +280,7 @@ static int _member_get_page(void* ctx, const char* ns, uint64_t prefix, int afte memset(buf + off, 0, 64); off += 64; uint64_t z = 0; memcpy(buf + off, &z, 8); off += 8; } - buf[off++] = nl; + buf[off++] = (uint8_t)(nl >> 8); buf[off++] = (uint8_t)nl; if (nl) { memcpy(buf + off, nm, nl); off += nl; } buf[off++] = (uint8_t)(atl >> 8); buf[off++] = (uint8_t)atl; if (atl) { memcpy(buf + off, atags, atl); off += atl; } @@ -893,7 +893,7 @@ void member_sync_verify_and_purge_all(struct UTUN_INSTANCE* inst) { struct member_wire { struct ms_member_rec rec; - char userinfo[256], tags[MS_ADM_TAGS_MAX + 1]; + char userinfo[MS_USERINFO_MAX + 1], tags[MS_ADM_TAGS_MAX + 1]; uint8_t local_join[64]; }; @@ -911,10 +911,10 @@ static int member_decode(const uint8_t* p, size_t len, struct member_wire* w, si if (len - off < 72) return -1; m->join_sig = p + off; off += 64; m->join_ts = member_read64(p + off); off += 8; } - if (len - off < 73) return -1; + if (len - off < 74) return -1; m->update_sig = p + off; off += 64; m->update_ts = member_read64(p + off); off += 8; - uint8_t n = p[off++]; - if (len - off < (size_t)n + 2 || memchr(p + off, 0, n)) return -1; + size_t n = ((size_t)p[off] << 8) | p[off + 1]; off += 2; + if (n > MS_USERINFO_MAX || len - off < n + 2 || memchr(p + off, 0, n)) return -1; memcpy(w->userinfo, p + off, n); off += n; size_t tags_len = ((size_t)p[off] << 8) | p[off + 1]; off += 2; if (tags_len > MS_ADM_TAGS_MAX || len - off < tags_len + 136 || memchr(p + off, 0, tags_len)) return -1; diff --git a/src/chat/member_sync.h b/src/chat/member_sync.h index ada046e6..cab7f8d9 100644 --- a/src/chat/member_sync.h +++ b/src/chat/member_sync.h @@ -30,6 +30,7 @@ struct sqlite3; /* UTF-8 JSON bytes, excluding NUL. A complete record fits in one Merkle page. */ #define MS_ADM_TAGS_MAX 8192 +#define MS_USERINFO_MAX 1024 /* Байты для подписи владельца: tags без NUL, затем node_id[8] в порядке байтов хоста. * Возвращает длину или -1, если данные/буфер не подходят. */ int member_sync_build_owner_msg(uint64_t node_id, const char* tags, uint8_t* out, size_t capacity);