Commit graph

113 commits

Author SHA1 Message Date
65323caaeb
chanserv: FLAGS maps sop/halfop presets to flag letters (oa=+ao), fixing privilege escalation when editing a HOP/SOP entry
All checks were successful
CI / check (push) Successful in 4m2s
2026-07-17 18:14:58 +00:00
5dcd216eeb
api: ordered Rank enum (founder>admin>op>halfop>voice) replaces the coarse u8 access rank, so PEACE distinguishes every tier
All checks were successful
CI / check (push) Successful in 3m59s
2026-07-17 17:33:53 +00:00
f2ba876ce4
botserv: bots join +ao (protected admin + op), keeping op alongside protect
All checks were successful
CI / check (push) Successful in 3m53s
2026-07-17 17:11:25 +00:00
73467b91ca
botserv: bots join channels as protected admins (+a) so ordinary ops can't kick or deop them
All checks were successful
CI / check (push) Successful in 3m50s
2026-07-17 16:52:00 +00:00
e2330c56ff
chanserv: SOP protect (+ao) and founder owner (+qo) with standard ~ & @ prefix tiers
All checks were successful
CI / check (push) Successful in 4m12s
2026-07-17 16:10:36 +00:00
b5aef650f2
chanserv: all op-and-above tiers grant +o for a single @ prefix; tier distinction stays in the access list
All checks were successful
CI / check (push) Successful in 4m12s
2026-07-17 15:58:11 +00:00
2f6fd41465
chanserv: SOP protect tier over AOP (+ao), founder owner (+qo); resolve op access by capability not mode string
All checks were successful
CI / check (push) Successful in 3m59s
2026-07-17 15:43:16 +00:00
c8106035df
chanserv: give SOP/AOP/HOP/VOP four distinct access tiers matching Anope, classified by capability
All checks were successful
CI / check (push) Successful in 3m55s
2026-07-17 14:54:36 +00:00
7a5f1502a4
infoserv: type the news kind as an enum at the store boundary
All checks were successful
CI / check (push) Successful in 3m53s
2026-07-17 13:53:53 +00:00
ef34c04c8d
operserv: type the X-line kind as an enum at the command/store boundary, wire token in storage 2026-07-17 13:47:10 +00:00
2c8ba4460d
forbid: type the FORBID kind as an enum at the store boundary, string only in storage
All checks were successful
CI / check (push) Successful in 3m56s
2026-07-17 13:26:16 +00:00
1fb3615b7e
auth: warn on unknown [[oper]] privilege names instead of silently dropping them
All checks were successful
CI / check (push) Successful in 3m53s
2026-07-17 12:45:41 +00:00
64b675e61f
operserv: REHASH reloads config live without a restart
All checks were successful
CI / check (push) Successful in 3m54s
2026-07-17 10:46:12 +00:00
75c6537532
standard replies: emit IRCv3 FAIL/WARN/NOTE for service errors, config-gated
All checks were successful
CI / check (push) Successful in 3m42s
2026-07-17 02:53:48 +00:00
66eb644a07
chanserv: channel-scoped seen with last message, replied in-channel
All checks were successful
CI / check (push) Successful in 3m47s
2026-07-17 01:41:47 +00:00
b87a0c56a2
services: label as network service in whois
All checks were successful
CI / check (push) Successful in 3m44s
2026-07-17 00:30:51 +00:00
eaf3111917 whois: answer IDLE for pseudo-clients 2026-07-16 23:22:35 +00:00
9bdda721f3 keycard: redeem website login keycards over SASL 2026-07-16 22:27:59 +00:00
2f9790feac
auth: offload IDENTIFY + SASL PLAIN verify off the engine lock
All checks were successful
CI / check (push) Successful in 3m47s
Both ran scram verify_plain (~1s PBKDF2 at 1.2M iters) inline under the engine
lock, freezing the whole daemon per login. Add NetAction::DeferAuthenticate +
AuthThen continuation + ctx.defer_authenticate, mirroring DeferPassword: the
module/SASL path fetches the verifier cheaply and defers; the link layer runs
verify_plain on spawn_blocking, then Engine::complete_authenticate finishes the
login (IDENTIFY reuses the same ctx helpers, so its login/AJOIN/vhost/memo
side-effects are unchanged). Tests resolve the defer inline (cfg(test)). The
gRPC web-login path was already fixed; no login path stalls services now.
(GHOST/DROP/CERT/GROUP still verify inline but are rare account ops, not logins.)
2026-07-16 19:04:18 +00:00
9d94dd5eb0
chanserv: support param mode locks (+f flood, +j joinflood)
Some checks failed
CI / check (push) Has been cancelled
Mode locks were char-only, so Anope FLOOD/JOINFLOOD locks were dropped on
migration. Carry a value per locked param-mode through the event log, MLOCK
parsing/display, drift enforcement, compaction, and the Anope importer, so a
migrated network keeps its flood protection verbatim.
2026-07-16 15:23:09 +00:00
61005f52f5
services: throttle emailed codes to stop RESEND/RESETPASS email-bombing
All checks were successful
CI / check (push) Successful in 3m46s
REGISTER was rate-limited but RESEND and RESETPASS weren't — anyone could
repeatedly request confirmation/reset codes for any account with an address
on file, flooding the victim's inbox and burning the service's sender
reputation. A per-account 60s cooldown (code_issue_wait, mirroring the vhost
request throttle) now gates both paths; guessing was already infeasible
(2^40 code + 5-try limit), so this closes the abuse, not an auth hole.
2026-07-16 10:41:52 +00:00
320a591ae3
engine: track the server tree so a hub SQUIT cascades
All checks were successful
CI / check (push) Successful in 3m50s
SQUIT arrives once for a splitting server (by SID), but a hub takes its
whole subtree with it — users behind downstream servers were left as stale
state. The parser now distinguishes a sourced downstream SERVER (tracked
with its parent) from the unsourced uplink handshake, the engine keeps the
SID->parent tree, and a SQUIT forgets every user across the departed
server's subtree. Tree is rebuilt each link. Wire formats verified against
the InspIRCd 4 m_spanningtree source.
2026-07-16 10:31:29 +00:00
4aff734340
engine: forget a split server's users on SQUIT
All checks were successful
CI / check (push) Successful in 3m47s
A netsplit is signalled once via SQUIT, not as a QUIT per user, so every
user behind the departed server lingered in services' state — stale
sessions, session-limit slots, and channel memberships. The parser now
surfaces ServerSplit and the engine forgets every uid carrying that
server's SID prefix, leaving other servers' users untouched.
2026-07-16 10:10:20 +00:00
63ecd79b12
engine: handle inbound KILL — forget users, reintroduce bots
KILL was never parsed, so a killed user lingered in services' state (stale
session, session-limit slot, channel membership) and a killed services bot
vanished for good. The parser now surfaces UserKilled; a killed real user is
forgotten like a QUIT (shared forget_user helper), while a killed bot is
dropped and reconciled so it is reintroduced and rejoins its channels.
2026-07-16 10:06:36 +00:00
7e868babc3
inspircd: restore logins from replayed accountname metadata
All checks were successful
CI / check (push) Successful in 3m45s
The inbound parser ignored METADATA entirely, so on a services netburst
(after a restart/relink) the ircd's replayed 'accountname' metadata was
dropped — every logged-in user looked logged out to services until they
re-identified, losing ChanServ access. Parse METADATA <uid> accountname
into a new AccountLogin event that restores account_of (empty = logout);
our own echoes and other keys are filtered.
2026-07-16 09:54:35 +00:00
01ea0fa95e
ChanServ: add SET EMAIL channel contact address
Founders can attach a contact email to a channel, shown in INFO and
cleared when set empty. Mirrors SET URL exactly; Local-scope channel
metadata. Completes the channel DESC/URL/EMAIL trio.
2026-07-16 03:06:08 +00:00
7eb1adce5e
ChanServ: add SET URL channel homepage
Founders can attach a homepage URL to a channel; it shows in INFO and
clears when set empty, mirroring SET DESC. Local-scope (channel metadata),
not gossiped, consistent with the entrymsg/description events.
2026-07-16 02:58:44 +00:00
053f8cf832
NickServ: add SET HIDE STATUS for last-seen privacy
Lets an account keep its last-seen/online line in INFO visible only to
itself and to opers. Default stays public (Anope's default). Accepts
STATUS (with USERMASK as an alias) per Anope's SET HIDE <field> grammar.
2026-07-16 02:33:55 +00:00
39d7421c06
NickServ: show last-seen (and online status) in INFO
The account's last-active time was tracked but never surfaced. INFO now
reports it, reading 'now (online)' when the account has a live session.
Threads NetView into the INFO handler for the session lookup and carries
last_seen on AccountView.
2026-07-16 01:56:51 +00:00
2c4bc9079c
NickServ: add SET KILL to toggle nick protection
Nick protection was unconditional. SET KILL OFF lets an account opt out —
an unidentified user keeping one of its nicks is no longer prompted or
renamed to a guest. Stored inverted (no_protect) so protection stays the
default. Accepts Anope's ON/QUICK/IMMED/OFF; grace is a fixed interval
here, so the finer variants simply enable protection like ON.
2026-07-16 01:43:10 +00:00
87e21ff85f
NickServ: add SET AUTOOP per-account auto-op opt-out
A user with SET AUTOOP OFF is never auto-opped on join, even where they
hold channel access — they op themselves via ChanServ UP. Stored inverted
(no_autoop) so the default stays auto-op. Join gates on both the channel
setting and the account preference; either can opt out.
2026-07-16 01:37:31 +00:00
0027decdb7
OperServ: add SET READONLY lockdown
All checks were successful
CI / check (push) Successful in 3m31s
2026-07-16 01:05:48 +00:00
b2442f85e6
OperServ: add SHUTDOWN and RESTART
All checks were successful
CI / check (push) Successful in 3m31s
2026-07-16 01:02:10 +00:00
dd43b9a331
BotServ: add BOTLIST and AUTOASSIGN default bot
All checks were successful
CI / check (push) Successful in 3m33s
2026-07-16 00:57:06 +00:00
961dc870da
MemoServ: add STAFF to memo all operators
Some checks failed
CI / check (push) Has been cancelled
2026-07-16 00:48:50 +00:00
d819b2c75f
MemoServ: add RSEND read receipts
Some checks failed
CI / check (push) Has been cancelled
2026-07-16 00:43:01 +00:00
2850620be1
ChanServ: add SET AUTOOP
All checks were successful
CI / check (push) Successful in 3m35s
SET AUTOOP {ON|OFF} controls whether access members are auto-opped/voiced
on join (on by default). Stored inverted as a settings flag so the
default stays on, and gated in the join handler.
2026-07-16 00:36:19 +00:00
2c282d036f
MemoServ: add SET NOTIFY and SET LIMIT
All checks were successful
CI / check (push) Successful in 3m35s
SET NOTIFY {ON|OFF} controls whether you're told about new memos on login;
SET LIMIT <n>|NONE sets your mailbox cap (honoured on SEND, NONE = the
network default). New memo_notify/memo_limit account fields + one
MemoPrefsSet event.
2026-07-16 00:29:33 +00:00
b5e08c33cf
MemoServ: add IGNORE
All checks were successful
CI / check (push) Successful in 3m34s
IGNORE ADD/DEL/LIST manages a per-account memo-ignore list; a memo from
an ignored account is silently dropped, and the sender is still told it
was sent so the ignore isn't revealed. New memo_ignore account field +
events, and a check in SEND.
2026-07-16 00:10:34 +00:00
ccbbb91fda
OperServ: add SVSPART
All checks were successful
CI / check (push) Successful in 3m36s
SVSPART <nick> <#channel> [reason] forces a user out of a channel
(admin-only), completing the SVS command family alongside SVSNICK and
SVSJOIN. New ForcePart action rendered as the ircd SVSPART command.
2026-07-16 00:00:18 +00:00
53d3d63464
NickServ GETEMAIL + ChanServ SET RESTRICTED
All checks were successful
CI / check (push) Successful in 3m51s
GETEMAIL (auspex) lists accounts whose email matches a glob. SET
RESTRICTED makes a channel kick anyone without access (or oper) as they
join, mirroring the SECUREOPS on-join enforcement.
2026-07-15 19:25:41 +00:00
be4860c9a8
OperServ: add FORBID (nick/channel/email registration bans)
All checks were successful
CI / check (push) Successful in 3m56s
FORBID ADD/DEL/LIST bans a NICK, CHAN, or EMAIL glob from being
registered — a network-wide policy that gossips like an AKILL and every
node enforces. Nick registration is blocked in pre_register_check (both
NickServ REGISTER and the account-registration relay), and channel
registration in ChanServ REGISTER. New Forbid store + events, mirroring
the akill subsystem.
2026-07-15 19:14:07 +00:00
ac50af92fc
ChanServ: add SET SUCCESSOR with founder inheritance
All checks were successful
CI / check (push) Successful in 3m59s
SET <#channel> SUCCESSOR <account>|OFF names an account that inherits the
channel if the founder's account is dropped or expires, instead of the
channel being released. Adds a ChannelInfo.successor field + event, and
centralises the founder-gone channel release into a single
release_founded_channels store method used by DROP, expiry, and the
gossip account-gone path so all three transfer consistently.
2026-07-15 18:58:08 +00:00
21efbd32c1
NickServ: add UPDATE and LIST
All checks were successful
CI / check (push) Successful in 3m46s
UPDATE re-applies your auto-joins and vhost and re-checks for waiting
memos without re-identifying. LIST (auspex-gated) shows registered
accounts matching a glob, capped at 100. Adds an accounts_matching store
method.
2026-07-15 18:24:52 +00:00
98ecbca414
MemoServ: add CANCEL, CHECK, and INFO
All checks were successful
CI / check (push) Successful in 3m49s
CANCEL recalls the sender's most recent unread memo to a target (one the
recipient already read can't be recalled); CHECK reports whether the last
memo you sent someone has been read; INFO summarises your mailbox. Adds
memo_cancel/memo_check store methods and shares MAX_MEMOS from the module
root instead of duplicating it in send.rs.
2026-07-15 18:09:33 +00:00
54ad013e49
Wire account registration to the ircd's ENCAP SWACCTREG/SWACCTRES relay
All checks were successful
CI / check (push) Successful in 3m53s
Echo is the authority the ircd account module forwards to: parse
ENCAP <us> SWACCTREG <reqid> <origin> <kind> <account> <p2> :<p3> into an
account request, and answer the origin server with
ENCAP <origin> SWACCTRES <reqid> <kind> <account> <status> <code> :<message>.
Thread the origin through the reply so responses route back to the
requesting server. Replaces the placeholder ACCTREGISTER/ACCTREGRESULT
names that nothing on the wire actually spoke.
2026-07-15 16:34:20 +00:00
0ed6684522
Validate config on load; document the SDK's core traits
Some checks failed
CI / check (push) Failing after 53s
Config::load now checks the SID is 3 alphanumeric chars and that
server.name and uplink.host are set, failing with a clear message
instead of a cryptic link-time error. Give the Service and Protocol
traits and ServiceCtx proper rustdoc so cargo doc is useful to module
authors.
2026-07-14 23:31:44 +00:00
d9c0878b00
Log store write failures at the source; share the oper guard
The store's map_err(|_| Internal) discarded the real IO error, so a
disk-full or permissions failure was invisible; log it once in the log
append path where it happens. Add echo_api::require_oper (parameterised
by the required privilege) and route the three copied per-service guards
through it, keeping each service's own wording and policy.
2026-07-14 23:19:00 +00:00
fcca8e4e3b
Front the whole network's help through HelpServ
Each service now exposes its help catalog via Service::help_topics; the
engine collects them into a network-wide index on Network, reachable
through two new NetView methods. HelpServ uses it: HELP <service>
[command] (or a bare service name) serves any service's per-command
help, bare HELP lists the services, and its own ticket commands still
work. No cross-crate dependency: the catalog flows through the SDK's
NetView, keeping every module dependent only on echo-api.
2026-07-14 18:37:45 +00:00
69a93198ff
Wire centralized HELP into the remaining services
ChanServ, BotServ, HostServ, MemoServ, OperServ, and StatServ now route
HELP through the shared renderer with per-command topic tables, so every
service supports HELP <command>. The renderer matches slash-grouped
names (OP/DEOP/VOICE/DEVOICE) so a paired command resolves as one topic.
Adds unit tests for the renderer.
2026-07-14 17:23:40 +00:00