callerid: scrub a departed/renamed nick from ACCEPT lists so it can't be reused to bypass +g

This commit is contained in:
Jean Chevronnet 2026-08-17 14:52:38 +00:00
parent c1b7ed6dda
commit 8ed2003546
2 changed files with 18 additions and 0 deletions

View file

@ -665,6 +665,12 @@ impl Server {
// socket itself once the channel is empty. // socket itself once the channel is empty.
if !user.nick.is_empty() { if !user.nick.is_empty() {
self.nick_index.remove(&user.nick.to_ascii_lowercase()); self.nick_index.remove(&user.nick.to_ascii_lowercase());
// Scrub the departed nick from every +g callerid ACCEPT list, so a new
// user grabbing this nick can't inherit its acceptance and bypass a gate.
let low = user.nick.to_ascii_lowercase();
for u in self.users.values_mut() {
u.accept.retain(|n| n != &low);
}
} }
if user.registered { if user.registered {
let line = format!(":{} QUIT :{reason}", user.prefix()); let line = format!(":{} QUIT :{reason}", user.prefix());

View file

@ -460,6 +460,18 @@ impl Server {
u.nick = newnick.to_string(); u.nick = newnick.to_string();
u.nick_ts = crate::server::now(); u.nick_ts = crate::server::now();
} }
// Keep +g callerid ACCEPT lists in step: move the entry from the old nick to
// the new one, so the freed old nick can't be grabbed to bypass someone's gate.
let (oldlow, newlow) = (old.to_ascii_lowercase(), newnick.to_ascii_lowercase());
if !old.is_empty() && oldlow != newlow {
for u in self.users.values_mut() {
for n in u.accept.iter_mut() {
if *n == oldlow {
*n = newlow.clone();
}
}
}
}
if registered { if registered {
let line = format!(":{prefix} NICK :{newnick}"); let line = format!(":{prefix} NICK :{newnick}");
let mut targets: HashSet<Uid> = HashSet::new(); let mut targets: HashSet<Uid> = HashSet::new();