|
|
924141683c
|
extbanbanlist: identify extbans by the real rule (<letter>:...) instead of "2nd byte is a colon" — the old heuristic wrongly skipped a plain hostmask whose second char happened to be ':', mis-listing it
|
2026-08-19 01:18:27 +00:00 |
|
|
|
6f9d11f83e
|
captcha: clamp recaptcha/cloudflare token TTL to [60s, 86400s] — an unclamped conf value could set exp in the past (every token instantly invalid, self-DoS) or absurdly far out
|
2026-08-19 01:18:13 +00:00 |
|
|
|
ee3c5e761e
|
geoip: bound recursion + require forward progress in the .mmdb value decoder — value_len/map_get recursed into nested maps/arrays with no depth limit (unlike resolve), so a crafted database could overflow the stack or spin on a zero-advance value; cap nesting at 32 and bail on a malformed (0-length) sub-value
|
2026-08-19 01:17:32 +00:00 |
|
|
|
e200779d27
|
connclass: resolve hash= independently of token order — the fold only ran if password= had already been parsed, so "hash=sha256 password=<hex>" (hash first) stored the digest as a plaintext password and every login to that class failed; build() now combines <algo>:<digest> after the full token pass
|
2026-08-19 01:15:26 +00:00 |
|
|
|
928026c49e
|
permchannels: isolate the load-time mode applier in catch_unwind so a panicking mode handler can't leave mode_sudo stuck true — which would silently disable rank/oper gating for every subsequent MODE; the flag is now always reset
|
2026-08-19 01:14:34 +00:00 |
|
|
|
14eb982db5
|
multiline: reject an over-limit batch with a FAIL instead of silently dropping the overflowing lines — accumulate() dropped a line that exceeded multiline_maxbytes/maxlines but still returned buffered=true, so the client believed a truncated message was sent whole; now overflow flags the batch and close() drops it with a standard FAIL
|
2026-08-19 01:13:39 +00:00 |
|
|
|
83cdce17c5
|
connflood: bound the per-IP connection-history map (prune stale buckets past 65536 tracked IPs) — it only shrank on the tick GC, so a wide source-IP spread could grow it unbounded between ticks (memory DoS)
|
2026-08-19 01:12:39 +00:00 |
|
|
|
a218d65371
|
rpc: authenticate on the header block before buffering the request body — the httpd read up to MAX_REQUEST (256 KiB) and only then checked the Authorization header, so an unauthenticated peer reaching rpc_bind could make each connection consume memory + a worker thread; now POST+auth are validated as soon as headers are complete, before any body is read
|
2026-08-19 01:05:29 +00:00 |
|
|
|
5b33786a46
|
rpc: refuse an all-wildcard x-line via ban.add — the mask went unvalidated, so an authenticated RPC call with "mask":"" or "*@*" installed a K/G/Z-line matching the entire network; require at least one literal host/ip/nick char
|
2026-08-19 01:03:27 +00:00 |
|
|
|
54c2a733fe
|
password_hash: reject a PBKDF2 credential with an absurd iteration count (>10M) instead of running it — the count is read straight from the stored string, so a corrupt/hostile credential (e.g. via a compromised accounts backend) could pin a worker thread for a very long time; legitimate work factors are far below the cap
|
2026-08-19 01:02:36 +00:00 |
|
|
|
35bb901455
|
whoisport: report the port the user actually connected to (User.port, set at accept) instead of conf("bind")/conf("bind_tls") — those are Vec-valued so conf() returned only the LAST configured listener, giving every user the same wrong port on a multi-listener server
|
2026-08-19 00:43:03 +00:00 |
|
|
|
25702c9541
|
syslog: strip control chars (CR/LF) from the message before framing — a snotice carrying user-influenced text (nick/realname/quit reason) with an embedded newline could inject a forged syslog record; matches the CR/LF care the JSON log path already takes
|
2026-08-19 00:42:30 +00:00 |
|
|
|
d9d5bd069b
|
filehost: refuse to sign upload tokens when filehost_jwt_secret is unset/empty/"changeme" — the default fell open, signing with a world-known key so anyone could forge a server-trusted upload authorization; now it fails closed and tells the user to fix the config
|
2026-08-19 00:42:10 +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 |
|
|
|
bbe4ee4567
|
http: bound spawn_http concurrency (http_max_concurrent, default 32) like spawn_crypto — it spawned one unbounded OS thread per call, so a pre-auth VERIFY/REGISTER flood could exhaust threads and hammer the accounts backend; at capacity the command now fails with TEMPORARILY_UNAVAILABLE instead
|
2026-08-19 00:39:01 +00:00 |
|
|
|
6682227f81
|
denychans: bound redirect recursion — a badchan redirect re-enters Server::join (which re-runs denychans), so a redirect loop (#a->#b->#a) or a redirect into a broad badchan glob recursed until the single-threaded daemon stack-overflowed from one JOIN; cap the chain at 8 hops via a RedirDepth guard in ext
|
2026-08-19 00:36:29 +00:00 |
|
|
|
a4f4c29a8a
|
connectban: clamp the IPv6 keep-hextets to >=1 — connectban_ipv6cidr between 1 and 15 made keep==0, so the z-line glob became "*" and banned every IPv6 address on the internet (and bucketed all v6 clients into one key); mirrors the v4 clamp(1,4)
|
2026-08-19 00:34:53 +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 |
|
|
|
d4dadf33e6
|
metrics: optional OpenMetrics/Prometheus endpoint (metrics_bind, off by default) — commands/messages/connects counters bumped inline via shared atomics, users/channels/servers/links gauges republished each tick; no event round-trip on the hot path
|
2026-08-18 22:34:36 +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 |
|
|
|
bcd958d2d3
|
ircv3: close server-support-table gaps — BOT=B ISUPPORT, account-extban (a: matcher + ACCOUNTEXTBAN=a), draft/read-marker cap (gates MARKREAD sync), and no-implicit-names (suppress the post-JOIN NAMES burst)
|
2026-08-18 15:56:59 +00:00 |
|
|
|
755e835baf
|
snoop: only announce a client's exit if it registered — an unregistered liveness/health probe was spamming the +q snomask (regression from firing on_user_quit for all users)
|
2026-08-17 22:49:29 +00:00 |
|
|
|
7563daf3a3
|
account_registration: GC the per-IP rate-limit table on the tick (an entry per distinct registering IP was never dropped)
|
2026-08-17 22:13:37 +00:00 |
|
|
|
fad66eaac2
|
chathistory: GC conversation keys idle past chathistory_maxage (default 7d) — the key set never shrank
|
2026-08-17 21:37:19 +00:00 |
|
|
|
f2e23fffa9
|
captcha: issue the challenge once per held client, not on every command they send
|
2026-08-17 20:37:51 +00:00 |
|
|
|
4b86de3b62
|
registration: add a Hold verdict so captcha/challenge modules pend the client for the challenge instead of tearing the link down
|
2026-08-17 19:06:17 +00:00 |
|
|
|
99eb9c74f3
|
relaymsg: gate RELAYMSG on oper (it spoofs an arbitrary source nick), matching InspIRCd
|
2026-08-17 19:06:17 +00:00 |
|
|
|
d6f27ac56c
|
securitygroups: honor tls=no/account=no/etc. instead of inverting them to require
|
2026-08-17 15:05:13 +00:00 |
|
|
|
edb10a6607
|
connectban: never collapse the ban mask to * on a sub-/8 CIDR (would z-line the whole network)
|
2026-08-17 15:05:13 +00:00 |
|
|
|
3d7ee6b586
|
reputation: count remote/services channel members toward the minchanmembers gate (score was frozen)
|
2026-08-17 13:27:58 +00:00 |
|
|
|
5722640957
|
s2s: handle echo's metadata profile keys, standard replies, OPERTYPE and REDACT; emit ssl_cert + OPERTYPE
|
2026-08-17 13:08:14 +00:00 |
|
|
|
0f28083855
|
markread: persist account-keyed read markers to disk and restore them at startup
|
2026-08-17 02:12:17 +00:00 |
|
|
|
b451ccbfd8
|
permchannels: persist +P channels (modes, topic, ts, list modes) to disk and restore them at startup
|
2026-08-17 01:43:29 +00:00 |
|
|
|
978f8f8f82
|
reputation: persist the score table on each bump/expire so restarts don't revert to a stale snapshot
|
2026-08-17 01:19:57 +00:00 |
|
|
|
6efbcb6db0
|
cloak: config-selectable methods (account, fingerprint, static) alongside the default hmac-sha256
|
2026-08-16 19:49:26 +00:00 |
|
|
|
04423388d5
|
services: reword uline/service code comments, drop external daemon references
|
2026-08-16 14:12:18 +00:00 |
|
|
|
7d57e4ed34
|
connectban: never flood-ban loopback (127.0.0.1/::1) and add a connectban_exempt glob/cidr list
|
2026-08-15 23:25:16 +00:00 |
|
|
|
546f6279e7
|
snomasks: make +s a parametric snomask mode with the standard category letters (acdfgjklnoqrtuvwx), route each server notice by category, RPL_SNOMASKIS 008; opers default to all and narrow with +s -c etc.
|
2026-08-15 17:06:14 +00:00 |
|
|
|
35af95fd0f
|
harden: connclass clone-cap at register, ws control-frame limits, uuid recycle-skip, json-escape extjwt/filehost claims, metadata value/key caps, cloak numeric-dotted leak, relaymsg remote-nick, rpc set_oper block validation, isupport 13-token split, multi-hop privmsg routing, connectdelay=0
|
2026-08-15 16:27:11 +00:00 |
|
|
|
e935ee7002
|
harden: fix reachable panics (parse_duration/parse_iso/dechunk char-boundary+overflow), s2s netburst key/limit loss, rpc set_nick/set_vhost/notice injection, webirc rehash reload, panic-state reset, ws line cap, remote nick collision, per-conn state leaks
|
2026-08-15 15:02:36 +00:00 |
|
|
|
3fa9737ccb
|
link: stop services re-locking +r on every join — track the registered channel mode, keep +r channels alive when empty, use ijoin not fjoin for incremental joins, and consume s2s channel-mode params through the registry
|
2026-08-15 13:20:04 +00:00 |
|
|
|
145a01b2c2
|
core: Server::disk_write — coalescing off-core snapshot writer; reputation/metadata saves no longer block the event loop on a slow disk
|
2026-08-12 13:16:15 +00:00 |
|
|
|
c231c6b8ef
|
connclass: verify a KDF class password off the core thread with a registration hold (auth_pending + Event::ConnclassAuth) — connect floods can't freeze the server
|
2026-08-12 13:13:27 +00:00 |
|
|
|
2b3495be65
|
customtitle: verify a KDF /TITLE password off the core thread (Event::TitleAuth) — /TITLE spam can't freeze the server
|
2026-08-12 13:07:28 +00:00 |
|
|
|
7cb58586b4
|
core: generic spawn_crypto helper; offload all slow KDF hashing (OPER pbkdf2 too, and MKPASSWD) off the core thread
|
2026-08-12 13:05:29 +00:00 |
|
|
|
b40c523b87
|
customprefix: data-driven prefix engine — define arbitrary new prefix modes (letter/prefix/rank/ranktoset/ranktounset/depriv), ranks re-spaced x10; built-in tiers + defaults unchanged
|
2026-08-11 19:46:07 +00:00 |
|
|
|
9f3081cb38
|
customprefix: add ranktoset/ranktounset/depriv per tier (InspIRCd change= parity for existing prefixes)
|
2026-08-11 19:20:27 +00:00 |
|
|
|
749a1c3b69
|
customprefix: config-override channel-prefix sigils per tier (customprefix = <tier> <sigil>); PREFIX/NAMES/FJOIN consistent
|
2026-08-11 19:01:45 +00:00 |
|
|
|
b4186ae08d
|
namedmodes: PROP command sets/queries channel modes by long name (op, moderated, limit, ...)
|
2026-08-11 18:55:14 +00:00 |
|
|
|
3b43abc88a
|
operlevels: oper = <name> <pass> <level>; a lower-level oper can't KILL a higher-level one
|
2026-08-11 18:50:12 +00:00 |
|