extbanbanlist: matching extban b:#chan (share another channel's ban list)
This commit is contained in:
parent
0d5717c585
commit
06883ced9f
5 changed files with 44 additions and 2 deletions
|
|
@ -120,6 +120,9 @@ amu_target = both
|
|||
# --- 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):
|
||||
# chanlog = #snotices
|
||||
# --- extbanbanlist (m_extbanbanlist): no config — adds the matching extban
|
||||
# `b:<#channel>`, so `+b b:#staff` catches everyone banned in #staff (shares a
|
||||
# ban list between channels).
|
||||
# --- relaymsg (m_relaymsg / draft/relaymsg): a member whose client negotiated the
|
||||
# capability can /RELAYMSG <#chan> <nick> <text> to speak under a spoofed relay
|
||||
# nick (for bridges). The nick must contain a separator and not collide.
|
||||
|
|
|
|||
|
|
@ -939,6 +939,7 @@ impl Server {
|
|||
Some(b'j') => crate::modules::channelban::matches(self, uid, &b.mask[2..]),
|
||||
Some(b's') => crate::modules::serverban::matches(self, uid, &b.mask[2..]),
|
||||
Some(b'G') => crate::modules::geoip::geoban_match(self, uid, &b.mask[2..]),
|
||||
Some(b'b') => crate::modules::extbanbanlist::matches(self, uid, &b.mask[2..]),
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1151,7 +1152,7 @@ pub fn normalize_ban_mask(m: &str) -> String {
|
|||
// These extbans carry a name / spec / channel / server, not a host mask,
|
||||
// so they must not be host-normalised: g: (security group), y: (reputation
|
||||
// score), r: (realname), j: (channel), s: (server name).
|
||||
if matches!(b[0], b'g' | b'y' | b'r' | b'j' | b's' | b'G') {
|
||||
if matches!(b[0], b'g' | b'y' | b'r' | b'j' | b's' | b'G' | b'b') {
|
||||
return m.to_string();
|
||||
}
|
||||
return format!("{}:{}", &m[..1], normalize_mask(&m[2..]));
|
||||
|
|
|
|||
37
src/modules/extbanbanlist.rs
Normal file
37
src/modules/extbanbanlist.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
//! extbanbanlist — the matching extban `b:<#channel>`: a user is caught if they are
|
||||
//! on `#channel`'s ban list. Lets one channel share (borrow) another's bans, e.g.
|
||||
//! `+b b:#staff` bans everyone banned in #staff. Reference: InspIRCd's
|
||||
//! `m_extbanbanlist`. Original native Rust.
|
||||
//!
|
||||
//! The match is deliberately *non-recursive* — it only tests the referenced
|
||||
//! channel's plain host-mask bans (and its plain excepts), never that channel's own
|
||||
//! extbans, so two channels referencing each other can't loop.
|
||||
|
||||
use crate::channels::glob_match;
|
||||
use crate::server::Server;
|
||||
use crate::Uid;
|
||||
|
||||
/// A plain host-mask ban entry (not itself an extban).
|
||||
fn is_plain(mask: &str) -> bool {
|
||||
mask.as_bytes().get(1) != Some(&b':')
|
||||
}
|
||||
|
||||
/// True if `uid` is on `chan`'s (plain) ban list with no matching plain exception.
|
||||
pub fn matches(s: &Server, uid: Uid, chan: &str) -> bool {
|
||||
let Some(who) = s.users.get(&uid).map(|u| u.prefix()) else {
|
||||
return false;
|
||||
};
|
||||
let Some(ch) = s.channels.get(&chan.to_ascii_lowercase()) else {
|
||||
return false;
|
||||
};
|
||||
if ch
|
||||
.excepts
|
||||
.iter()
|
||||
.any(|e| is_plain(&e.mask) && glob_match(&e.mask, &who))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ch.bans
|
||||
.iter()
|
||||
.any(|b| is_plain(&b.mask) && glob_match(&b.mask, &who))
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ pub mod dccallow;
|
|||
pub mod denychans;
|
||||
pub mod disable;
|
||||
pub mod dnsbl;
|
||||
pub mod extbanbanlist;
|
||||
pub mod extended_isupport;
|
||||
pub mod extjwt;
|
||||
pub mod filehost;
|
||||
|
|
|
|||
|
|
@ -596,7 +596,7 @@ impl Server {
|
|||
let maxnick = self.conf_num("maxnick", 30usize);
|
||||
let maxchan = self.conf_num("maxchannel", 50usize);
|
||||
let mut lines = vec![format!(
|
||||
"CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beIgXw,k,lfjFLHBJdK,ACDGMNOPQRSTUcimnpstuz EXTBAN=,Gcgjmnrsy WATCH={maxwatch} MONITOR={maxmon} SILENCE={maxsil} CALLERID=g WHOX CHATHISTORY={chathist} MSGREFTYPES=timestamp,msgid UTF8ONLY CASEMAPPING=ascii NICKLEN={maxnick} CHANNELLEN={maxchan} NETWORK={}",
|
||||
"CHANTYPES=# PREFIX=(qaohv)~&@%+ CHANMODES=beIgXw,k,lfjFLHBJdK,ACDGMNOPQRSTUcimnpstuz EXTBAN=,Gbcgjmnrsy WATCH={maxwatch} MONITOR={maxmon} SILENCE={maxsil} CALLERID=g WHOX CHATHISTORY={chathist} MSGREFTYPES=timestamp,msgid UTF8ONLY CASEMAPPING=ascii NICKLEN={maxnick} CHANNELLEN={maxchan} NETWORK={}",
|
||||
self.network
|
||||
)];
|
||||
if let Some(tok) = crate::modules::network_icon::isupport(self) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue