From a772587a39da8cef0a44ed779b155550aa67ca74 Mon Sep 17 00:00:00 2001 From: reverse Date: Sat, 8 Aug 2026 20:21:27 +0000 Subject: [PATCH] stats: oper-gate the sensitive letters, add e/q/shun x-lines and l (links) --- src/coremods/core_extra.rs | 30 ++++++++++++++++++++++++++++-- src/numeric.rs | 1 + 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/coremods/core_extra.rs b/src/coremods/core_extra.rs index b0bcbb1..0902597 100644 --- a/src/coremods/core_extra.rs +++ b/src/coremods/core_extra.rs @@ -213,6 +213,20 @@ impl Command for Stats { } fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult { let letter = params[0].chars().next().unwrap_or(' '); + // everything but uptime exposes server internals — opers only + if letter != 'u' && !s.is_oper(uid) { + s.numeric( + uid, + ERR_NOPRIVILEGES, + ":Permission Denied- You're not an IRC operator", + ); + s.numeric( + uid, + RPL_ENDOFSTATS, + &format!("{letter} :End of /STATS report"), + ); + return CmdResult::Fail; + } match letter { 'u' => { let up = now().saturating_sub(s.created); @@ -229,11 +243,14 @@ impl Command for Stats { s.numeric(uid, RPL_STATSOLINE, &format!("O * * {n} :oper")); } } - 'k' | 'g' | 'z' => { + 'k' | 'g' | 'z' | 'e' | 'q' | 's' => { let kind = match letter { 'k' => XKind::Kline, 'g' => XKind::Gline, - _ => XKind::Zline, + 'z' => XKind::Zline, + 'e' => XKind::Eline, + 'q' => XKind::Qline, + _ => XKind::Shun, }; let rows: Vec = s .xlines @@ -254,6 +271,15 @@ impl Command for Stats { s.numeric(uid, RPL_STATSXLINE, &r); } } + 'l' => { + for sv in s.servers.values() { + s.numeric( + uid, + RPL_STATSLINKINFO, + &format!("{} 0 0 0 0 :{}", sv.name, sv.desc), + ); + } + } _ => {} } s.numeric( diff --git a/src/numeric.rs b/src/numeric.rs index 70a3f48..0bdf01c 100644 --- a/src/numeric.rs +++ b/src/numeric.rs @@ -2,6 +2,7 @@ pub const RPL_MAP: u16 = 6; pub const RPL_MAPEND: u16 = 7; +pub const RPL_STATSLINKINFO: u16 = 211; // STATS l — a server link pub const RPL_STATSCOMMANDS: u16 = 212; pub const RPL_ENDOFSTATS: u16 = 219; pub const RPL_STATSUPTIME: u16 = 242;