Reject ambiguous DM parties sharing an identity

This commit is contained in:
evgeny committed 2026-11-03 12:09:56 +01:00
1 parent c26d9e9a71
commit cf2880596c
2 files changed
+12 -4

No files matched your search

+8 -3
View File
@@ -46,6 +46,11 @@ int dm_party_equal(const struct dm_party* a, const struct dm_party* b) {
return a && b && a->kind == b->kind && a->node == b->node && !memcmp(a->ed, b->ed, 32) && !memcmp(a->x, b->x, 32);
}
/* Разные ключи одного ID означают конфликт, а не вторую сторону беседы. */
static int party_same_id(const struct dm_party* a, const struct dm_party* b) {
return a->kind == b->kind && (a->kind == DM_PARTY_DEVICE ? a->node == b->node : !memcmp(a->ed, b->ed, 32));
}
/* Собственное устройство берём из ядра, удалённое — из проверенной проекции nodes. */
int dm_party_resolve(struct UTUN_INSTANCE* inst, uint64_t node, enum dm_mode mode, struct dm_party* out) {
if (!inst || !inst->topo_sqlite_db || !node || !out || (mode != DM_MODE_DEVICE && mode != DM_MODE_GROUPS))
@@ -129,7 +134,7 @@ int dm_party_private(struct UTUN_INSTANCE* inst, const struct dm_party* party, u
uint64_t dm_identity_conv_id(enum dm_mode mode, const struct dm_party parties[2]) {
if (!parties || (mode != DM_MODE_DEVICE && mode != DM_MODE_GROUPS) || !party_valid(parties) ||
!party_valid(parties + 1) || dm_party_equal(parties, parties + 1)) {
!party_valid(parties + 1) || party_same_id(parties, parties + 1)) {
identity_error(NULL, "invalid conversation parties", 0); return 0;
}
if (mode == DM_MODE_DEVICE) {
@@ -171,9 +176,9 @@ static int target_compare(const void* a, const void* b) {
int dm_identity_targets(struct UTUN_INSTANCE* inst, const struct dm_party parties[2],
struct dm_target* out, size_t capacity, size_t* count) {
if (!inst || !inst->topo_sqlite_db || !parties || !out || !count || !capacity ||
!party_valid(parties) || !party_valid(parties + 1) || dm_party_equal(parties, parties + 1))
!party_valid(parties) || !party_valid(parties + 1) || party_same_id(parties, parties + 1))
return identity_error(inst, "invalid recipient snapshot arguments", 0);
struct dm_target targets[DM_TARGET_MAX]; size_t n = 0;
struct dm_target targets[DM_TARGET_MAX] = {{0}}; size_t n = 0;
for (unsigned side = 0; side < 2; side++) {
const struct dm_party* party = parties + side;
if (party->kind == DM_PARTY_DEVICE) {
+4 -1
View File
@@ -67,7 +67,7 @@ int main(void) {
assert(!dm_party_resolve(&inst, nodes[0].node_id, DM_MODE_DEVICE, direct));
assert(!dm_party_resolve(&inst, nodes[2].node_id, DM_MODE_DEVICE, direct + 1));
assert(dm_identity_conv_id(DM_MODE_DEVICE, direct) == dm_derive_conv_id(nodes[0].node_id, nodes[2].node_id));
struct dm_target targets[DM_TARGET_MAX]; size_t count = 99;
struct dm_target targets[DM_TARGET_MAX] = {{0}}; size_t count = 99;
assert(!dm_identity_targets(&inst, direct, targets, DM_TARGET_MAX, &count) && count == 2);
assert(has_target(targets, count, nodes[0].node_id, 0) && has_target(targets, count, nodes[2].node_id, 1));
assert(!dm_party_resolve(&inst, nodes[1].node_id, DM_MODE_DEVICE, direct + 1));
@@ -100,6 +100,9 @@ int main(void) {
reversed[0] = parties[0]; reversed[1] = parties[0];
assert(!dm_identity_conv_id(DM_MODE_GROUPS, reversed));
assert(dm_identity_targets(&inst, reversed, targets, DM_TARGET_MAX, &count) < 0);
reversed[1].x[0] ^= 1;
assert(!dm_identity_conv_id(DM_MODE_GROUPS, reversed));
assert(dm_identity_targets(&inst, reversed, targets, DM_TARGET_MAX, &count) < 0);
group(nodes + 2, group_ed[1], group_x[1], "Renamed peer devices", 2);
assert(!devgroup_project(inst.topo_sqlite_db, nodes + 2));