Proof of concept mechanical port of ircnet/ircd to Rust as part of a bit about C being insecure for network services
0

Configure Feed

Select the types of activity you want to include in your feed.

ircd.rs / docs / claude-memory / leveva-config-ban-enforcement.md
4.1 kB

name: leveva-config-ban-enforcement description: "leveva P11 slice 191 — static config ban (K-line) blocks are now enforced at registration (were silently dead); the config_ban_match pure core, the kline_exempt-gated finalize gate, and why no-resolve/xline-exempt stay deferred by design" metadata: node_type: memory type: project originSessionId: 41caad9f-3671-4d56-9ee6-9d5e75bb53b7#

P11 slice 191 fixed a silent gap: config.bans (the parsed ban { mask; reason; gecos } blocks — the C static K-line) was never enforced. ServerContext::from_config started klines: KlineStore::new() empty and nothing read config.bans — only runtime TKLINEs (ctx.klines) bit, so an admin's static ban blocks did nothing.

Now enforced at session::finalize_registration, after the runtime K-line gate, gated by !admission.kline_exempt (static bans are K-lines → the I-line CFLAG_KEXEMPT exemption bypasses them too). Pure core: kline::config_ban_match(bans, user, host, realname) -> Option<&Ban> — the first ban whose user@host mask matches (CIDR-aware, via the shared matching::allow_host_matches) and whose optional gecos glob-matches the realname (None ignores it). Refusal = 465 :You (user@host) are banned … : <reason> + ERROR :Closing Link … (Kill line active: <reason>) + closing. A *@* mask + a gecos pattern is a realname/X-line ban.

Live/rehash: held via the slice-91 live-or-ctx ConfStore idiom — bans added to StatsConf (boot fallback), ConfBlocks/config_conf, ConfStore + control::live_bans(); seeded in main.rs. REHASH re-reads ban blocks (see [[leveva-rehash-matrix]]).

Why the other two slice-190 "carried-not-acted" allow attrs stay DEFERRED BY DESIGN (not a backlog): no-resolve is inert — leveva is IP-only (client host = peer.ip().to_string(), no reverse DNS anywhere, leveva_iauth::AuthVerdict has no hostname field) so there is no resolved hostname to suppress; xline-exempt has no separate X-line list because a gecos'd static ban already subsumes realname bans. Don't "implement" either without first building the absent underlying feature (reverse DNS / a distinct X-line block).

Follow-on CLOSED (slice 192): STATS k now appends one 216 RPL_STATSKLINE per static config ban (k <host> <user> :<reason>, no ttl — absent integer marks a permanent ban, 4 params vs the runtime t-kline's 5) after the runtime KlineStore, read live-or-ctx. Pure core stats::config_ban_report + split_ban_mask (last-@ split); gecos folds into the reason trailing. Config bans stay under lowercase k (unified view); uppercase K stays recognized-but- empty. Tests: stats units + stats_k_appends_one_216_per_config_ban proptest + golden_stats_config_ban.rs.

Follow-on CLOSED (slice 197): the kline-exempt I-line flag (the C CFLAG_KEXEMPT → persistent FLAGS_EXEMPT) is now honoured at runtime TKLINE reaping, not just the two registration-time gates. It was consumed at registration and never stored, so an already-registered exempt client got reaped anyway by an operator's later matching TKLINE. Fix: new ClientRecord.kline_exempt field (default false; remote/test claims are never local K-line targets) + Registry::set_kline_exempt setter, mirrored from admission.kline_exempt in finalize_registration (next to set_class); command::tkline's reap loop now continues past rec.kline_exempt before the mask test (the ban is still laid — exemption protects the client, not the ban). Tests: tkline_does_not_reap_a_kline_exempt_connection unit + set_kline_exempt_toggles… registry unit + a_kline_exempt_iline_marks_the_record_exempt session unit + kline_proptest::exempt_clients_are_never_reaped (ejected set == covered ∧ ¬exempt).

Tests: kline::config_ban_match_* units + config_ban_match_equals_a_reference_scan proptest; session gate tests (a_config_banned_host_is_refused_465 + inverses + the exempt bypass); golden_rehash_ban.rs boot-golden (enforce + live reload). Recording per [[leveva-slice-recording]].