M5: moderation, permissions, channel CRUD, in-app account management

- Server-side moderation & permissions (kick/ban/move/server-mute, channel CRUD).

- Database schema v2: channels, bans; BLAKE2b channel passwords, Argon2id accounts.

- C ABI additions and client-side handling (vc_kick_user, vc_ban_user, vc_set_permission, vc_set_server_mute, vc_move_user, vc_create/edit/delete_channel, vc_create/reset/delete/list_account).

- vccli flags for all M5 operations plus --username/--password auth.

- Four new tests covering permissions, kick/ban/move/mute, admin accounts, channel CRUD.

- Docs: protocol.md envelope updates, security.md channel-password hashing, PROGRESS.md.
This commit is contained in:
2026-06-17 15:08:05 +02:00
parent a2f159e971
commit 3990f63f0f
23 changed files with 3281 additions and 97 deletions

View File

@@ -117,7 +117,7 @@ Binding works as:
hashed with **Argon2id** (via libsodium `crypto_pwhash`) using per-install-tuned memory/time
parameters; never stored or logged in plaintext. Verification runs on the worker pool (it's
deliberately slow) to avoid stalling the net thread.
- **Channel passwords:** hashed at rest too; join attempts compare server-side.
- **Channel passwords:** hashed at rest with **BLAKE2b** (libsodium `crypto_generichash`) plus a per-channel salt. BLAKE2b is used instead of Argon2id here because channel-password checks happen on the net thread during `JoinChannelRequest`; a slow hash would block real-time message processing. The password itself still crosses the wire only inside TLS 1.3.
- **Brute-force defense:** per-IP and per-account rate limiting on auth attempts with
exponential backoff; configurable lockout. Generic `auth_request` failures return a
non-enumerating error ("invalid credentials") to avoid username probing.
@@ -126,7 +126,7 @@ Binding works as:
accounts( id INTEGER PK, username TEXT UNIQUE,
pw_argon2id TEXT, -- encoded hash incl. params + salt
created_at, last_login, flags )
bans( id, subject_type, subject, reason, expires_at )
bans( id, subject_type, subject, reason, expires_at, created_at )
```
## 5. Permissions (scaffold for v1, enforced server-side)