services: label as network service in whois
All checks were successful
CI / check (push) Successful in 3m44s
All checks were successful
CI / check (push) Successful in 3m44s
This commit is contained in:
parent
952078aa7e
commit
b87a0c56a2
5 changed files with 29 additions and 1 deletions
|
|
@ -73,6 +73,9 @@ pub enum NetAction {
|
||||||
// Answer a remote IDLE request for one of our pseudo-clients so a routed
|
// Answer a remote IDLE request for one of our pseudo-clients so a routed
|
||||||
// WHOIS completes: `:<target> IDLE <requester> <signon> <idle>`.
|
// WHOIS completes: `:<target> IDLE <requester> <signon> <idle>`.
|
||||||
IdleReply { target: String, requester: String, signon: u64, idle: u64 },
|
IdleReply { target: String, requester: String, signon: u64, idle: u64 },
|
||||||
|
// Flag one of our pseudo-clients as a services operator so WHOIS labels it a
|
||||||
|
// network service (the oper line): `:<uid> OPERTYPE :<oper_type>`.
|
||||||
|
OperType { uid: String, oper_type: String },
|
||||||
IntroduceUser { uid: String, nick: String, ident: String, host: String, gecos: String },
|
IntroduceUser { uid: String, nick: String, ident: String, host: String, gecos: String },
|
||||||
Privmsg { from: String, to: String, text: String },
|
Privmsg { from: String, to: String, text: String },
|
||||||
Notice { from: String, to: String, text: String },
|
Notice { from: String, to: String, text: String },
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,11 @@ impl Protocol for InspIrcd {
|
||||||
NetAction::IdleReply { target, requester, signon, idle } => {
|
NetAction::IdleReply { target, requester, signon, idle } => {
|
||||||
vec![format!(":{target} IDLE {requester} {signon} {idle}")]
|
vec![format!(":{target} IDLE {requester} {signon} {idle}")]
|
||||||
}
|
}
|
||||||
|
// Oper up a pseudo-client (legacy form, no privilege tags = full access;
|
||||||
|
// the type name is what WHOIS shows: "is a <oper_type>").
|
||||||
|
NetAction::OperType { uid, oper_type } => {
|
||||||
|
vec![format!(":{uid} OPERTYPE :{oper_type}")]
|
||||||
|
}
|
||||||
// insp4 UID: uuid nickts nick realhost disphost realuser dispuser ip signonts +modes :gecos
|
// insp4 UID: uuid nickts nick realhost disphost realuser dispuser ip signonts +modes :gecos
|
||||||
// (both a real AND a displayed user field — see m_spanningtree/uid.cpp Builder).
|
// (both a real AND a displayed user field — see m_spanningtree/uid.cpp Builder).
|
||||||
NetAction::IntroduceUser { uid, nick, ident, host, gecos } => vec![self.sourced(format!(
|
NetAction::IntroduceUser { uid, nick, ident, host, gecos } => vec![self.sourced(format!(
|
||||||
|
|
|
||||||
|
|
@ -285,10 +285,18 @@ pub struct Server {
|
||||||
// services server U-lined), bot, block-CTCP. Set per the ircd's loaded modules.
|
// services server U-lined), bot, block-CTCP. Set per the ircd's loaded modules.
|
||||||
#[serde(default = "default_service_modes")]
|
#[serde(default = "default_service_modes")]
|
||||||
pub service_modes: String,
|
pub service_modes: String,
|
||||||
|
// Oper type the service pseudo-clients are flagged with, so WHOIS shows
|
||||||
|
// "is a <this>". Default "Network Service". Empty leaves them non-opers.
|
||||||
|
#[serde(default = "default_service_oper_type")]
|
||||||
|
pub service_oper_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_service_modes() -> String {
|
fn default_service_modes() -> String {
|
||||||
"iHkBT".to_string()
|
"ikBT".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_service_oper_type() -> String {
|
||||||
|
"Network Service".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_protocol() -> u32 {
|
fn default_protocol() -> u32 {
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ pub struct Engine {
|
||||||
synced: bool,
|
synced: bool,
|
||||||
guest_nick: String, // base for the Guest#### rename on enforcement
|
guest_nick: String, // base for the Guest#### rename on enforcement
|
||||||
service_host: String, // hostname the service pseudo-clients wear
|
service_host: String, // hostname the service pseudo-clients wear
|
||||||
|
service_oper_type: String, // oper type our services are flagged with (WHOIS "is a <this>"); empty = don't oper
|
||||||
enforce_seq: u32, // counter appended to guest_nick
|
enforce_seq: u32, // counter appended to guest_nick
|
||||||
pending_enforce: Vec<PendingEnforce>, // registered nicks awaiting identify-or-rename
|
pending_enforce: Vec<PendingEnforce>, // registered nicks awaiting identify-or-rename
|
||||||
bot_uids: HashMap<String, String>, // casefolded bot nick -> live uid (per connection)
|
bot_uids: HashMap<String, String>, // casefolded bot nick -> live uid (per connection)
|
||||||
|
|
@ -238,6 +239,7 @@ impl Engine {
|
||||||
synced: false,
|
synced: false,
|
||||||
guest_nick: "Guest".to_string(),
|
guest_nick: "Guest".to_string(),
|
||||||
service_host: "services.local".to_string(),
|
service_host: "services.local".to_string(),
|
||||||
|
service_oper_type: String::new(),
|
||||||
enforce_seq: 0,
|
enforce_seq: 0,
|
||||||
pending_enforce: Vec::new(),
|
pending_enforce: Vec::new(),
|
||||||
bot_uids: HashMap::new(),
|
bot_uids: HashMap::new(),
|
||||||
|
|
@ -771,6 +773,11 @@ impl Engine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Oper type our services are flagged with at introduction (empty = don't oper).
|
||||||
|
pub fn set_service_oper_type(&mut self, oper_type: impl Into<String>) {
|
||||||
|
self.service_oper_type = oper_type.into();
|
||||||
|
}
|
||||||
|
|
||||||
// A user arrived on (or changed to) a registered nick: if they aren't logged
|
// A user arrived on (or changed to) a registered nick: if they aren't logged
|
||||||
// into that account, prompt them to IDENTIFY and schedule a rename. Gated on
|
// into that account, prompt them to IDENTIFY and schedule a rename. Gated on
|
||||||
// `synced` so a netburst can't enforce every already-online user; a user who
|
// `synced` so a netburst can't enforce every already-online user; a user who
|
||||||
|
|
@ -929,6 +936,10 @@ impl Engine {
|
||||||
host: self.service_host.clone(),
|
host: self.service_host.clone(),
|
||||||
gecos: svc.gecos().to_string(),
|
gecos: svc.gecos().to_string(),
|
||||||
});
|
});
|
||||||
|
// Oper them up so WHOIS labels them a network service (the oper line).
|
||||||
|
if !self.service_oper_type.is_empty() {
|
||||||
|
out.push(NetAction::OperType { uid: svc.uid().to_string(), oper_type: self.service_oper_type.clone() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Advertise our SASL mechanisms so the uplink can offer `sasl=PLAIN` to
|
// Advertise our SASL mechanisms so the uplink can offer `sasl=PLAIN` to
|
||||||
// clients in CAP LS (IRCv3 SASL 3.2).
|
// clients in CAP LS (IRCv3 SASL 3.2).
|
||||||
|
|
|
||||||
|
|
@ -189,6 +189,7 @@ async fn main() -> Result<()> {
|
||||||
// Service pseudo-clients wear the configured host, or the server name.
|
// Service pseudo-clients wear the configured host, or the server name.
|
||||||
let service_host = if cfg.server.service_host.is_empty() { &cfg.server.name } else { &cfg.server.service_host };
|
let service_host = if cfg.server.service_host.is_empty() { &cfg.server.name } else { &cfg.server.service_host };
|
||||||
engine.lock().await.set_service_host(service_host);
|
engine.lock().await.set_service_host(service_host);
|
||||||
|
engine.lock().await.set_service_oper_type(cfg.server.service_oper_type.clone());
|
||||||
engine.lock().await.set_log_channel(cfg.log.as_ref().map(|l| l.channel.clone()));
|
engine.lock().await.set_log_channel(cfg.log.as_ref().map(|l| l.channel.clone()));
|
||||||
if enabled("debugserv") {
|
if enabled("debugserv") {
|
||||||
// DebugServ speaks the live feed into the log channel; give the engine its uid.
|
// DebugServ speaks the live feed into the log channel; give the engine its uid.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue