globops + autodrop: /GLOBOPS oper broadcast and pre-registration scanner drop

This commit is contained in:
Jean Chevronnet 2026-08-10 08:58:15 +00:00
parent ab4d87488b
commit 512185d6df
4 changed files with 89 additions and 0 deletions

View file

@ -120,6 +120,11 @@ amu_target = both
# --- chanlog (m_chanlog): mirror the oper server-notice stream into a channel so # --- chanlog (m_chanlog): mirror the oper server-notice stream into a channel so
# staff can watch it in a normal window. Set the channel (create/keep it opped): # staff can watch it in a normal window. Set the channel (create/keep it opped):
# chanlog = #snotices # chanlog = #snotices
# --- globops (m_globops): no config — adds the oper command /GLOBOPS <message>,
# broadcasting to all opers (like the server-notice stream).
# --- autodrop (m_autodrop): silently drop a not-yet-registered client that sends
# any of these commands (HTTP scanners blurt GET/POST before NICK/USER):
# autodrop_commands = GET POST HEAD CONNECT PUT DELETE OPTIONS TRACE PATCH
# --- hidelist (m_hidelist): list modes (+b/+e/+I/…) are viewable by members by # --- hidelist (m_hidelist): list modes (+b/+e/+I/…) are viewable by members by
# default; this restricts a given list to a minimum rank. Repeatable, # default; this restricts a given list to a minimum rank. Repeatable,
# `hidelist = <modechar> <rank>` (rank: owner|admin|op|halfop|voice). Opers see # `hidelist = <modechar> <rank>` (rank: owner|admin|op|halfop|voice). Opers see

45
src/modules/autodrop.rs Normal file
View file

@ -0,0 +1,45 @@
//! autodrop — silently drop a not-yet-registered client that sends one of the
//! configured commands. HTTP scanners and other junk open a connection and blurt
//! `GET` / `POST` / `CONNECT` before ever sending NICK/USER; a real IRC client
//! never does. Config, space-separated (repeatable):
//!
//! ```text
//! autodrop_commands = GET POST HEAD CONNECT PUT DELETE OPTIONS TRACE PATCH
//! ```
//!
//! Reference: InspIRCd's `m_autodrop`. Original native Rust.
use crate::module::{ModResult, Module};
use crate::server::Server;
use crate::Uid;
pub struct AutoDrop;
impl Module for AutoDrop {
fn name(&self) -> &'static str {
"autodrop"
}
fn on_pre_command(
&mut self,
s: &mut Server,
uid: Uid,
cmd: &str,
_params: &[String],
) -> ModResult {
// only before registration — a registered client's commands are its own
if s.users.get(&uid).map(|u| u.registered).unwrap_or(true) {
return ModResult::Passthru;
}
let hit = s
.conf_all("autodrop_commands")
.iter()
.any(|line| line.split_whitespace().any(|w| w.eq_ignore_ascii_case(cmd)));
if hit {
s.send(uid, "ERROR :Closing link (dropped)".to_string());
s.remove_user(uid, "Autodropped");
return ModResult::Deny;
}
ModResult::Passthru
}
}

35
src/modules/globops.rs Normal file
View file

@ -0,0 +1,35 @@
//! globops — `GLOBOPS <message>` lets an oper send a message to all opers (the
//! server-notice stream, echoIRCd's equivalent of InspIRCd's `+g` snomask).
//! Reference: InspIRCd's `m_globops`. Original native Rust.
use crate::command::{CmdResult, Command};
use crate::numeric::ERR_NOPRIVILEGES;
use crate::server::Server;
use crate::Uid;
pub fn commands() -> Vec<Box<dyn Command>> {
vec![Box::new(GlobopsCmd)]
}
struct GlobopsCmd;
impl Command for GlobopsCmd {
fn name(&self) -> &'static str {
"GLOBOPS"
}
fn min_params(&self) -> usize {
1
}
fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult {
if !s.is_oper(uid) {
s.numeric(
uid,
ERR_NOPRIVILEGES,
":Permission Denied- You're not an IRC operator",
);
return CmdResult::Fail;
}
let nick = s.users.get(&uid).map(|u| u.nick.clone()).unwrap_or_default();
s.snotice(&format!("GLOBOPS from {nick}: {}", params.join(" ")));
CmdResult::Ok
}
}

View file

@ -6,6 +6,7 @@
pub mod account_registration; pub mod account_registration;
pub mod antimixedutf8; pub mod antimixedutf8;
pub mod antirandom; pub mod antirandom;
pub mod autodrop;
pub mod autoop; pub mod autoop;
pub mod banredirect; pub mod banredirect;
pub mod blockamsg; pub mod blockamsg;
@ -29,6 +30,7 @@ pub mod filehost;
pub mod filter; pub mod filter;
pub mod flood; pub mod flood;
pub mod geoip; pub mod geoip;
pub mod globops;
pub mod hashident; pub mod hashident;
pub mod hidelist; pub mod hidelist;
pub mod hidewhois; pub mod hidewhois;
@ -93,6 +95,7 @@ pub fn default_modules() -> Vec<Box<dyn Module>> {
Box::new(dccallow::DccAllow), Box::new(dccallow::DccAllow),
Box::new(solvemsg::SolveMsg), Box::new(solvemsg::SolveMsg),
Box::new(autoop::AutoOp), Box::new(autoop::AutoOp),
Box::new(autodrop::AutoDrop),
] ]
} }
@ -127,5 +130,6 @@ pub fn module_commands() -> Vec<Box<dyn Command>> {
.chain(customtitle::commands()) .chain(customtitle::commands())
.chain(dccallow::commands()) .chain(dccallow::commands())
.chain(geoip::commands()) .chain(geoip::commands())
.chain(globops::commands())
.collect() .collect()
} }