operserv: NOTIFY lines carry real IP, rdns, login and origin server for the oper feed
All checks were successful
CI / check (push) Successful in 4m4s
All checks were successful
CI / check (push) Successful in 4m4s
This commit is contained in:
parent
2fb1970030
commit
4d327c3f47
2 changed files with 24 additions and 3 deletions
|
|
@ -390,8 +390,28 @@ impl Engine {
|
|||
if !self.db.notify_flags(Some(&target), chan).contains(flag) {
|
||||
return None;
|
||||
}
|
||||
// The feed lands in the oper-only staff channel, so a watch line carries the
|
||||
// forensic detail a cloak hides: the real IP (with rdns if it differs), the
|
||||
// login, and the origin server. The connection port is not available — the
|
||||
// ircd's s2s UID burst never sends it. `nick!ident@host` keeps the cloak so
|
||||
// it still correlates with what ordinary users see.
|
||||
let mut parts: Vec<String> = Vec::new();
|
||||
if !target.ip.is_empty() {
|
||||
let mut s = format!("\x02{}\x02", target.ip);
|
||||
if !target.realhost.is_empty() && target.realhost != target.ip {
|
||||
s.push_str(&format!(" ({})", target.realhost));
|
||||
}
|
||||
parts.push(s);
|
||||
}
|
||||
if let Some(account) = target.account {
|
||||
parts.push(format!("acct \x02{account}\x02"));
|
||||
}
|
||||
if !target.server.is_empty() {
|
||||
parts.push(format!("via {}", target.server));
|
||||
}
|
||||
let detail = if parts.is_empty() { String::new() } else { format!(" · {}", parts.join(" · ")) };
|
||||
let who = format!("\x02{}\x02!{}@{}", target.nick, target.ident, target.host);
|
||||
self.feed("NOTIFY", format!("{who} {what}"))
|
||||
self.feed("NOTIFY", format!("{who} {what}{detail}"))
|
||||
}
|
||||
|
||||
// Inactivity-expiry thresholds (seconds); None leaves that kind never
|
||||
|
|
|
|||
|
|
@ -5408,8 +5408,9 @@ fn notify_hook_emits_feed_for_watched_user() {
|
|||
let out = e.handle(NetEvent::UserAttrs { uid: "000AAAAAC".into(), ident: "x".into(), realhost: "h".into(), gecos: "g".into() });
|
||||
assert!(
|
||||
out.iter().any(|a| matches!(a, NetAction::Privmsg { from, to, text }
|
||||
if from == "42SAAAAAO" && to == "#services" && text.contains("[NOTIFY]") && text.contains("connected"))),
|
||||
"expected a NOTIFY connect line, got {out:?}"
|
||||
if from == "42SAAAAAO" && to == "#services" && text.contains("[NOTIFY]") && text.contains("connected")
|
||||
&& text.contains("1.2.3.4"))), // the real IP is carried, not just the cloak
|
||||
"expected a NOTIFY connect line with the real IP, got {out:?}"
|
||||
);
|
||||
// A clean user draws nothing.
|
||||
e.handle(NetEvent::UserConnect { uid: "000AAAAAD".into(), nick: "nice".into(), host: "h".into(), ip: "9.9.9.9".into() });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue