asn: A:<asn> matching extban (ban/exempt by origin AS); advertise A in EXTBAN

This commit is contained in:
Jean Chevronnet 2026-08-28 18:53:04 +00:00
parent 068924de86
commit bf1446a51b
No known key found for this signature in database
GPG key ID: 439666D63A9477E4
3 changed files with 9 additions and 2 deletions

View file

@ -1337,7 +1337,7 @@ impl Server {
/// Whether any entry in `list` catches `uid`: a plain `nick!user@host` glob, or
/// a matching extban (`g:` group, `y:` reputation, `r:` realname, `j:` channel,
/// `s:` server, `G:` geoip, `b:` banlist). Acting extbans (`m:`/`c:`/`n:`) never
/// `s:` server, `G:` geoip, `A:` asn, `b:` banlist). Acting extbans (`m:`/`c:`/`n:`) never
/// match here — they restrict actions, not join/ban membership.
pub fn ban_list_hit(&self, uid: Uid, list: &[Ban]) -> bool {
let who = self.users.get(&uid).map(|u| u.prefix()).unwrap_or_default();
@ -1353,6 +1353,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'A') => crate::modules::asn::extban_match(self, uid, &b.mask[2..]),
Some(b'b') => crate::modules::extbanbanlist::matches(self, uid, &b.mask[2..]),
_ => false,
}

View file

@ -48,6 +48,12 @@ pub fn user_in(s: &Server, uid: Uid, list: &[u32]) -> bool {
!list.is_empty() && of(s, uid).is_some_and(|a| list.contains(&a))
}
/// The `A:<asn[,asn]>` matching extban: is `uid`'s origin AS one of the listed AS
/// numbers? The `AS` prefix is optional — e.g. `+b A:15169` or `+b A:AS3215,16276`.
pub fn extban_match(s: &Server, uid: Uid, spec: &str) -> bool {
user_in(s, uid, &parse_list(spec))
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -941,7 +941,7 @@ impl Server {
let include_oper = self.conf_bool("operprefix", false) || self.conf_bool("ojoin", false);
let prefix = crate::modules::customprefix::isupport(include_oper);
let mut tokens: Vec<String> = format!(
"CHANTYPES=# PREFIX={prefix} CHANMODES=beIgXw,k,lfjFLHBJdK,ACDGMNOPQRSTUcimnprstuz EXTBAN=,aGbcgjmnrsy ACCOUNTEXTBAN=a BOT=B WATCH={maxwatch} MONITOR={maxmon} SILENCE={maxsil} CALLERID=g WHOX CHATHISTORY={chathist} MSGREFTYPES=timestamp,msgid UTF8ONLY CASEMAPPING=ascii NICKLEN={maxnick} CHANNELLEN={maxchan} MODES={maxmodes} NETWORK={}",
"CHANTYPES=# PREFIX={prefix} CHANMODES=beIgXw,k,lfjFLHBJdK,ACDGMNOPQRSTUcimnprstuz EXTBAN=,aGAbcgjmnrsy ACCOUNTEXTBAN=a BOT=B WATCH={maxwatch} MONITOR={maxmon} SILENCE={maxsil} CALLERID=g WHOX CHATHISTORY={chathist} MSGREFTYPES=timestamp,msgid UTF8ONLY CASEMAPPING=ascii NICKLEN={maxnick} CHANNELLEN={maxchan} MODES={maxmodes} NETWORK={}",
network
)
.split(' ')