Keep unresolved invitation chains inactive and test interrupted sync and cycles
This commit is contained in:
1 parent
e7b850f3ea
commit
a1653d648b
3 files changed
+18
-8
No files matched your search
@@ -158,7 +158,7 @@ static int gp_load(struct UTUN_INSTANCE* inst, const char* ch, struct gp_member*
|
||||
int tree = member_sync_verify_signature(db, ch, &m);
|
||||
if (tree == MS_VERIFY_ERROR) goto done;
|
||||
p->valid = verified == 1 && tree == 1 && !sqlite3_column_int(st, 12) && memcmp(m.join_sig, (uint8_t[64]){0}, 64);
|
||||
if (p->valid && m.adm_tags && m.adm_tags_sig) {
|
||||
if (p->valid && m.adm_tags && m.adm_tags_sig && memcmp(m.adm_tags_sig, (uint8_t[64]){0}, 64)) {
|
||||
char role[MS_ADM_TAGS_MAX + 1];
|
||||
if (!json_flat_get(m.adm_tags, "admin", role, sizeof(role))) {
|
||||
const char* last = role;
|
||||
|
||||
@@ -1277,7 +1277,7 @@ static int member_finish(void* ctx, const char* ns) {
|
||||
if (sqlite3_column_bytes(st, 1) != 32 || sqlite3_column_bytes(st, 3) != 64) { rc = SQLITE_CORRUPT; break; }
|
||||
if (_sig_is_zero64(m.signature)) continue;
|
||||
int verified = member_sync_verify_signature(db, ns, &m);
|
||||
if (verified != 1) {
|
||||
if (verified != 1 && verified != MS_VERIFY_DEFERRED) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: cannot confirm ns=%s node=%016llx signer=%016llx verification=%d",
|
||||
MS_ID, ns, (unsigned long long)m.node_id, (unsigned long long)m.signed_by, verified);
|
||||
rc = SQLITE_CONSTRAINT; break;
|
||||
@@ -1304,15 +1304,18 @@ static void member_policy_result(void* ctx, const char* ns, uint64_t peer, int r
|
||||
}
|
||||
if (group_policy_refresh(inst, ns)) return;
|
||||
struct ready_member { uint64_t node, signer; uint8_t x[32], signature[64]; };
|
||||
struct ready_member* rows = NULL; size_t count = 0;
|
||||
struct ready_member* rows = NULL; size_t count = 0, capacity = 0;
|
||||
char sql[192]; sqlite3_stmt* st = NULL;
|
||||
snprintf(sql, sizeof(sql), "SELECT node_id,signed_by,x25519_pubkey,signature FROM peers_%s WHERE admitted=1 AND deleted=0", ns);
|
||||
int rc = sqlite3_prepare_v2(_db(inst), sql, -1, &st, NULL);
|
||||
if (rc == SQLITE_OK) while ((rc = sqlite3_step(st)) == SQLITE_ROW) {
|
||||
if (sqlite3_column_bytes(st, 2) != 32 || sqlite3_column_bytes(st, 3) != 64) { rc = SQLITE_CORRUPT; break; }
|
||||
if (count >= UINT32_MAX / sizeof(*rows) - 1) { rc = SQLITE_TOOBIG; break; }
|
||||
struct ready_member* p = u_realloc(rows, (count + 1) * sizeof(*rows));
|
||||
if (!p) { rc = SQLITE_NOMEM; break; } rows = p;
|
||||
if (count == capacity) {
|
||||
size_t next = capacity ? capacity * 2 : 16;
|
||||
if (next > UINT32_MAX / sizeof(*rows)) { rc = SQLITE_TOOBIG; break; }
|
||||
struct ready_member* p = u_realloc(rows, next * sizeof(*rows));
|
||||
if (!p) { rc = SQLITE_NOMEM; break; } rows = p; capacity = next;
|
||||
}
|
||||
rows[count].node = (uint64_t)sqlite3_column_int64(st, 0); rows[count].signer = (uint64_t)sqlite3_column_int64(st, 1);
|
||||
memcpy(rows[count].x, sqlite3_column_blob(st, 2), 32); memcpy(rows[count].signature, sqlite3_column_blob(st, 3), 64); count++;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
static uint8_t group_x[32] = {81}, group_private[32] = {82}, group_public[32];
|
||||
struct person { uint64_t id; uint8_t x[32], ed[32], private[32], join[64], tree[64], role[64]; };
|
||||
static struct person people[6];
|
||||
static struct person people[8];
|
||||
|
||||
static void public_key(const uint8_t private[32], uint8_t public[32]) {
|
||||
EVP_PKEY* key = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, private, 32); assert(key);
|
||||
@@ -51,7 +51,7 @@ static void page(struct UTUN_INSTANCE* src, struct UTUN_INSTANCE* dst, uint64_t
|
||||
int main(void) {
|
||||
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN);
|
||||
struct UASYNC* ua = uasync_create(); assert(ua); public_key(group_private, group_public);
|
||||
for (unsigned i = 0; i < 6; i++) {
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
struct person* p = &people[i]; p->x[0] = i + 1; p->private[0] = i + 11;
|
||||
public_key(p->private, p->ed); p->id = sc_derive_node_id_from_pubkey(p->x);
|
||||
uint8_t body[112]; assert(member_sync_build_join_msg(group_x, group_public, p->id, p->x, 1, body, sizeof(body)) == 112);
|
||||
@@ -90,6 +90,8 @@ int main(void) {
|
||||
assert(!topo_node_sqlite_member_get_sign(source.topo_sqlite_db, "1001", people[3].id, &signer, signature) && !signer);
|
||||
/* Политика раньше переподписи: текущий допуск сохраняется до полной контрольной точки. */
|
||||
page(&source, &target, 0); assert(admitted(&target, 3) && admitted(&target, 4));
|
||||
member_sync_destroy(&target); assert(!member_sync_init(&target));
|
||||
assert(admitted(&target, 3) && admitted(&target, 4) && group_policy_pending(target.topo_sqlite_db, "1001") == 1);
|
||||
const uint64_t mask = ~UINT64_C(0) << (64 - MT_MAX_LEVEL * 5);
|
||||
for (unsigned i = 0; i < 6; i++) page(&source, &target, people[i].id & mask);
|
||||
assert(admitted(&target, 3) && admitted(&target, 4));
|
||||
@@ -104,6 +106,11 @@ int main(void) {
|
||||
struct ms_member_rec forged = {.node_id = people[3].id, .x25519 = people[3].x, .join_sig = people[4].join,
|
||||
.signature = signature, .signed_by = 0};
|
||||
assert(member_sync_verify_signature(source.topo_sqlite_db, "1001", &forged) == 0);
|
||||
put_person(&source, 6, 7); assert(!admitted(&source, 6) && !member_finish(&source, "1001"));
|
||||
put_person(&source, 7, 6); assert(!admitted(&source, 6) && !admitted(&source, 7));
|
||||
token(&source, baseline);
|
||||
assert(!group_policy_command(&source, "1001", 1, baseline, NULL, &json)); u_free(json);
|
||||
assert(!admitted(&source, 6) && !admitted(&source, 7));
|
||||
member_sync_destroy(&source); member_sync_destroy(&target);
|
||||
assert(sqlite3_close(source.topo_sqlite_db) == SQLITE_OK && sqlite3_close(target.topo_sqlite_db) == SQLITE_OK);
|
||||
uasync_destroy(ua, 0); puts("PASS: default, roles, cascade, selection, rollback, stale preview, page order, signature precedence, restart");
|
||||
|
||||
Reference in new issue
Block a user