Commit graph

135 commits

Author SHA1 Message Date
6bb8ccd8ee
modules: draft/event-playback — record JOIN/PART/QUIT/NICK/MODE/TOPIC/KICK into CHATHISTORY, replayed only for cap clients (event_playback config, default on) 2026-08-25 22:17:26 +00:00
04671733d2
i18n: localize the client-facing Closing-link ERROR wrapper via trf (fr, es); QUIT-broadcast reasons stay canonical for S2S 2026-08-25 14:35:13 +00:00
9b51db07f5
i18n: sweep all remaining dynamic prose (oper commands, XLINE/FILTER/DNSBL notices, whois/vhost/knock/dcc/title/reputation/tline/rmode, hash, rename) through trf; +\xNN catalog escape; fr+es now 236 entries each 2026-08-25 14:30:29 +00:00
ef96bcbd06
i18n: localize the snotice/announce path — translate at deliver_server_notice chokepoint; rehash, connect/exit, oper-up, login, channel & ojoin notices via trf (fr, es) 2026-08-25 13:04:31 +00:00
f36f803d42
whois: show client-cert fingerprint (276) to everyone, not just opers/self 2026-08-24 22:25:08 +00:00
009bea734a
whois: show negotiated TLS version/group/cipher in 671; sslgroup crate reads the KEX group 2026-08-24 21:45:46 +00:00
42fe82556b
version: show echoircd-<major> (5) in 002/004/351 and enrich RPL_VERSION with build/toolchain provenance 2026-08-23 01:24:45 +00:00
70a4ecb0a0
core: add oper MODULES command (702/703) listing loaded modules; module.list RPC already existed 2026-08-22 17:36:46 +00:00
73817eddde
whois: show a remote user's actual server description in 312, not the literal "remote user" 2026-08-21 23:43:51 +00:00
3ad67c6b52
xline: broadcast the XLINE notice on remove and expire too, so it covers every x-line's whole lifecycle 2026-08-21 15:03:36 +00:00
1824af5d90
signore: persist per-account via services metadata — push on edit, replay on login 2026-08-20 15:40:19 +00:00
6c5f330746
add SIGNORE: personal mutual server-side ignore across channels and PMs 2026-08-20 14:48:17 +00:00
2c9ce18cd7
whois: render the oper-type title line in bold + colour (per-type color=<name|0-15|none>, default red) so it stands out 2026-08-20 14:26:17 +00:00
bc520d59a5
whois: a typed oper gets its own 320 special line with the type title (e.g. 'is a Network Administrator'), separate from the generic 313 operator line 2026-08-20 14:17:15 +00:00
8f9e60c8e2
whois: 313 shows the generic 'is an IRC Operator' again — the oper type gates capabilities, and a custom title comes from the SWHOIS line (320) 2026-08-20 14:05:46 +00:00
5a9825ee61
comments: strip stray reference-implementation names from a handful of module/inline comments 2026-08-20 10:11:07 +00:00
01516d5fdc
opertypes: oper classes + types — reusable capability classes and named roles (WHOIS title, auto usermodes/snomasks/vhost + level on oper-up, per-type command enforcement via on_pre_command); ships 5 built-in (helpop/globop/admin/servadmin/netadmin); oper blocks gain type=<id>; a typeless oper keeps full access 2026-08-20 10:05:11 +00:00
16fae5b23c watch: notify WATCH/MONITOR via nick->watchers reverse indexes (watch_by/monitor_by) instead of scanning every user on each online/offline/nick-change flip — O(watchers) not O(users); maintained through centralized watch_index_*/monitor_index_* helpers + quit cleanup 2026-08-19 02:34:22 +00:00
16ea4b5a23 core_message: compute the sender's channel rank once per message (mrank) instead of recomputing s.rank(uid,&key) up to 7x in the channel PRIVMSG/NOTICE gate and once more in TAGMSG — rank is fixed for a single message 2026-08-19 02:29:59 +00:00
fb1a9f3d70 server: skip the O(users) callerid ACCEPT scrub on quit unless the departing nick is actually accepted by someone — a reverse count (accepted_nicks) maintained through centralized accept_add/accept_remove helpers avoids scanning every user's accept list on each quit (O(users*quits) on a netsplit); the full scrub still runs when the count is nonzero, so the nick-reuse protection is unchanged 2026-08-19 02:21:38 +00:00
ab0ccae71f server: scrub a departed user's pending invites via a User.invited reverse index instead of scanning every channel on the network per quit — the old O(channels)-per-quit path was O(channels*quits) on a netsplit; the index is maintained at the 4 invite add/remove sites (INVITE cmd, S2S INVITE, join-consume, UNINVITE) 2026-08-19 02:09:36 +00:00
5101b1361d whois: build the target snapshot as a named WhoisInfo struct instead of a 17-field positional tuple — field-named construction can't silently transpose two same-typed fields; destructured into the same locals so the reply code is unchanged 2026-08-19 01:58:01 +00:00
d495fd0f30 channel: cap the per-channel invite set (maxinvites, default 100) — it only shrank when the invitee joined, so an op could grow it unboundedly; re-inviting an already-listed nick still works 2026-08-19 01:22:32 +00:00
4248cc0479 oper: gate the client-facing SVSLOGIN/SVSLOGOUT behind oper_svslogin (default off) — they were a pre-S2S stopgap that let any oper forge an arbitrary account login (set_login) and thus +r/account-gated access; the live path is S2S link_svslogin (source_is_service-gated), so services are unaffected — only the obsolete oper backdoor is closed 2026-08-19 01:01:33 +00:00
a09dfc74df auth: constant-time compare for VHOST and WEBIRC secrets — both used plain == on the config password, unlike oper/RPC/JWT secrets which already route through ct_eq; expose password_hash::ct_eq as the shared comparator and use it (usernames stay plain == — not secret) 2026-08-19 00:41:47 +00:00
c72b966e0a mode: cap mode changes per MODE command (modes=, default 20) and advertise it as the MODES= ISUPPORT token — an uncapped modestring like MODE #c +bbbb… dispatched a handler per letter, each fanning out to the whole channel and every S2S link (amplification DoS); matches InspIRCd's MODES limit 2026-08-19 00:40:58 +00:00
c99f16f3e0 webirc: require a non-empty source-IP mask on a webirc block — an empty ipmask meant "any IP", so a maskless webirc=<password> block turned one shared secret into a full host/IP spoof (bypassing z-lines, DNSBL, GeoIP, cloak) for anyone who learned it; now the gateway's connecting IP must match the block's ipmask 2026-08-19 00:34:25 +00:00
235c747c03 refactor: WEBIRC gateways and +G censor rules are named structs (WebircGateway/CensorRule) instead of positional tuples — self-documenting field access, no (_, g, _) index guessing; extends the OperBlock pattern 2026-08-18 23:31:21 +00:00
c4456cf002 oper: TLS client-cert fingerprint login — oper block gains an optional fp=<sha256>; password=* means cert-only. Named OperBlock struct replaces the (name,pass,level) tuple. (Password login was never broken — verified live.) 2026-08-18 22:55:07 +00:00
853be58d18 perf: channel PRIVMSG/NOTICE fanout builds at most one line per capability profile (server-time/account-tag/message-tags) and shares it by Arc, instead of formatting a String per member — a big channel now allocates <=8 lines, not N 2026-08-18 22:37:50 +00:00
a3dc7b521f test: deterministic two-node S2S convergence simulator — real handshake + join/part/rejoin/FJOIN-TS-arbitration driven through actual code paths, proptest-randomised churn asserts both sides always converge; extract Server::part so the sim and the PART command share one path 2026-08-18 22:24:19 +00:00
20b49add0b perf: mimalloc global allocator + aHash maps + memchr line framer + LTO/codegen-units=1 — ~29% faster channel fanout; and drop the bogus openssl+mio dependency whitelist from the guard (any perf crate is welcome now) 2026-08-18 19:45:33 +00:00
c9bd8e7492 channel-rename: implement IRCv3 draft/channel-rename — RENAME command + cap, in-place rename (RENAME for cap clients, PART/JOIN fallback for the rest), and S2S propagation 2026-08-17 23:45:02 +00:00
e28efb03e6 callerid: cap the auto-accept list like the explicit ACCEPT command 2026-08-17 21:37:19 +00:00
73f8ff58ed s2s: enforce servprotect on a remote KILL and rank-vs-victim on a remote KICK (matching the local paths) 2026-08-17 19:38:58 +00:00
58d5a0e5a5 message: keep +U opmoderated messages out of CHATHISTORY/+H replay, and subject TAGMSG to the same PM gates (+c/+R/+z/+g/SILENCE) 2026-08-17 15:05:13 +00:00
480b5faea0 sanick/svsnick: allow a case-only rename (in-use check matched the target itself) 2026-08-17 14:52:38 +00:00
713406870b who: hide +u auditorium and +D delayjoin members on WHO #chan, matching NAMES 2026-08-17 14:52:38 +00:00
3f9aa8c6eb channel: cull an empty channel when a mode change (-P/-r) removes its last reason to persist 2026-08-17 01:50:11 +00:00
262699bf30 kick: route KICK of a remote channel member to its server and drop the local view 2026-08-16 19:31:49 +00:00
ef84846267 invite: route INVITE for a remote target to its server and deliver inbound INVITE 2026-08-16 19:11:57 +00:00
559a102e48 add oper SQUIT command to disconnect a linked server by name 2026-08-16 19:10:29 +00:00
767ecb3471 whois: fold the channel list across multiple 319 lines to stay under 512 bytes 2026-08-16 18:46:07 +00:00
94f57608f7 mode: require half-op to view the autoop/exemptchanops/filter lists 2026-08-16 18:44:08 +00:00
dadbff91d8 xline: accept the durationless KLINE/GLINE form (mask :reason) instead of eating the reason 2026-08-16 18:21:32 +00:00
5046083608 add HELP command with a built-in index and per-topic help (704/705/706) 2026-08-16 18:20:57 +00:00
ba9d62b172 cap: advertise IRCv3 sts policy (sts_duration/sts_port/sts_preload) for TLS upgrade 2026-08-16 18:19:04 +00:00
4ce500e525 cap: fold CAP LS 302 into multiple continuation lines to stay under 512 bytes 2026-08-16 18:17:29 +00:00
7908fe50b0 s2s: propagate x-lines (ADDLINE/DELLINE) — apply from peers, announce local ones, burst on link 2026-08-16 18:01:52 +00:00
98fb848b8c s2s: route and apply KILL across the link (inbound handler + remote-target routing) 2026-08-16 17:57:50 +00:00