operprefix + ojoin: server oper prefix (!/mode y, above owner) auto-granted to opers + OJOIN command
This commit is contained in:
parent
8ebb106f97
commit
1dd7f77ca8
106 changed files with 687 additions and 711 deletions
|
|
@ -24,9 +24,9 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
]
|
||||
}
|
||||
|
||||
/// TBAN — set a +b ban that lifts itself after a duration (InspIRCd `m_timedbans`).
|
||||
/// `TBAN <#chan> <duration> <mask>`; needs half-op or above. The background tick
|
||||
/// removes it and announces `MODE -b` when it expires.
|
||||
/// TBAN — set a +b ban that lifts itself after a duration. `TBAN <#chan>
|
||||
/// <duration> <mask>`; needs half-op or above. The background tick removes it and
|
||||
/// announces `MODE -b` when it expires.
|
||||
struct Tban;
|
||||
impl Command for Tban {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -313,8 +313,8 @@ impl Command for Invite {
|
|||
}
|
||||
}
|
||||
|
||||
/// UNINVITE — revoke a pending invite (InspIRCd `m_uninvite`). `UNINVITE <nick>
|
||||
/// <#chan>`; a channel op cancels an invite they (or another op) issued.
|
||||
/// UNINVITE — revoke a pending invite. `UNINVITE <nick> <#chan>`; a channel op
|
||||
/// cancels an invite they (or another op) issued.
|
||||
struct Uninvite;
|
||||
impl Command for Uninvite {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ impl Command for Info {
|
|||
fn handle(&self, s: &mut Server, uid: Uid, _params: &[String]) -> CmdResult {
|
||||
for line in [
|
||||
format!("echoircd-{VERSION} — a from-scratch IRC daemon in Rust"),
|
||||
"Modeled on InspIRCd's API; #![forbid(unsafe_code)]".to_string(),
|
||||
"Memory-safe by construction; no unsafe code".to_string(),
|
||||
format!("Running the {} network", s.network),
|
||||
] {
|
||||
s.numeric(uid, RPL_INFO, &format!(":{line}"));
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
]
|
||||
}
|
||||
|
||||
/// SSLINFO — report a user's TLS status and client-cert fingerprint (InspIRCd
|
||||
/// `m_sslinfo`). You may query yourself; querying another user requires oper.
|
||||
/// SSLINFO — report a user's TLS status and client-cert fingerprint. You may
|
||||
/// query yourself; querying another user requires oper.
|
||||
struct SslInfo;
|
||||
impl Command for SslInfo {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -649,7 +649,7 @@ impl Command for Notice {
|
|||
|
||||
/// TAGMSG — an IRCv3 message that carries only client tags (typing, reactions, …)
|
||||
/// and no text. Relayed to targets whose clients enabled `message-tags`; clients
|
||||
/// without it never see it. Mirrors PRIVMSG's target / membership / +m rules.
|
||||
/// without it never see it. Applies PRIVMSG's target / membership / +m rules.
|
||||
struct TagMsg;
|
||||
impl Command for TagMsg {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
//! core_mode — the MODE command. Both channel and user modes are dispatched to
|
||||
//! the handler objects in [`crate::mode`] (InspIRCd-style `ModeHandler`s); this
|
||||
//! file just parses the modestring and orchestrates.
|
||||
//! MODE: parse the modestring and dispatch each letter to its handler in
|
||||
//! [`crate::mode`] (channel and user modes alike).
|
||||
|
||||
use crate::channels::RANK_HALFOP;
|
||||
use crate::command::{CmdResult, Command};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//! core_oper — IRC operator commands: OPER, KILL, WALLOPS. Mirrors InspIRCd's
|
||||
//! `coremods/core_oper/`. Oper blocks are configured with `oper = name pass`.
|
||||
//! IRC operator commands: OPER, KILL, WALLOPS, the SA*/SVS* set, X-lines, and
|
||||
//! the oper CHG*/SET* tools. Oper blocks are configured with `oper = name pass`.
|
||||
|
||||
use crate::channels::Topic;
|
||||
use crate::command::{CmdResult, Command};
|
||||
|
|
@ -56,8 +56,8 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
]
|
||||
}
|
||||
|
||||
/// OPERMOTD — show the IRC-operators' message of the day (InspIRCd `m_opermotd`),
|
||||
/// configured with repeated `opermotd = <line>` entries.
|
||||
/// OPERMOTD — show the IRC-operators' message of the day, configured with
|
||||
/// repeated `opermotd = <line>` entries.
|
||||
struct OperMotd;
|
||||
impl Command for OperMotd {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -95,7 +95,7 @@ impl Command for OperMotd {
|
|||
}
|
||||
|
||||
/// An oper-set WHOIS line, stored per-user in `User.ext` and rendered by WHOIS
|
||||
/// (RPL_WHOISSPECIAL 320). InspIRCd `m_swhois`.
|
||||
/// (RPL_WHOISSPECIAL 320).
|
||||
pub struct Swhois(pub String);
|
||||
|
||||
/// Reject non-opers with 481; returns whether the caller is an oper.
|
||||
|
|
@ -178,11 +178,11 @@ impl Command for Kill {
|
|||
}
|
||||
}
|
||||
|
||||
/// SVSLOGIN / SVSLOGOUT — the **services interface** to the account layer
|
||||
/// ([`crate::accounts`]). Over S2S these arrive from a services pseudoserver
|
||||
/// (Anope/Atheme); until S2S exists an oper may invoke them to drive `+r` and the
|
||||
/// account-gated channel modes. `SVSLOGIN <nick> <account>` logs a user in
|
||||
/// (`account` of `*`/`0` logs out); `SVSLOGOUT <nick>` logs them out.
|
||||
/// SVSLOGIN / SVSLOGOUT — the services interface to the account layer
|
||||
/// ([`crate::accounts`]). Over S2S these arrive from a services pseudoserver;
|
||||
/// until S2S exists an oper may invoke them to drive `+r` and the account-gated
|
||||
/// channel modes. `SVSLOGIN <nick> <account>` logs a user in (`account` of `*`/`0`
|
||||
/// logs out); `SVSLOGOUT <nick>` logs them out.
|
||||
struct SvsLogin;
|
||||
impl Command for SvsLogin {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -415,8 +415,8 @@ impl Command for SaNick {
|
|||
}
|
||||
|
||||
// --- SVS* : the services interface. Same enforcement as the SA* oper commands,
|
||||
// under the names a services package speaks (like SVSLOGIN). Gated to opers/
|
||||
// services; a linked services pseudoserver drives these once S2S routes them.
|
||||
// under the names a services package speaks. Gated to opers/services; a linked
|
||||
// services pseudoserver drives these once S2S routes them.
|
||||
|
||||
/// SVSNICK — force a nick change (nick-registration enforcement). An optional
|
||||
/// third param is the new-nick TS, accepted and ignored (single-TS model).
|
||||
|
|
@ -729,7 +729,7 @@ impl Command for Qline {
|
|||
}
|
||||
|
||||
/// CBAN — forbid a channel-name glob (opers bypass it). Mask alone removes; a
|
||||
/// mask + duration adds. InspIRCd `m_cban`.
|
||||
/// mask + duration adds.
|
||||
struct Cban;
|
||||
impl Command for Cban {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -743,8 +743,8 @@ impl Command for Cban {
|
|||
}
|
||||
}
|
||||
|
||||
/// NICKLOCK — force a user's nick and lock it so they can't change it (InspIRCd
|
||||
/// `m_nicklock`). `NICKLOCK <nick> <newnick>`; opers/services still can.
|
||||
/// NICKLOCK — force a user's nick and lock it so they can't change it.
|
||||
/// `NICKLOCK <nick> <newnick>`; opers/services still can.
|
||||
struct NickLock;
|
||||
impl Command for NickLock {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1122,8 +1122,8 @@ impl Command for SaKick {
|
|||
}
|
||||
}
|
||||
|
||||
/// SAQUIT — force a user to quit the network (InspIRCd `m_saquit`). Looks to
|
||||
/// everyone like a normal client QUIT.
|
||||
/// SAQUIT — force a user to quit the network. Looks to everyone like a normal
|
||||
/// client QUIT.
|
||||
struct SaQuit;
|
||||
impl Command for SaQuit {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1151,8 +1151,8 @@ impl Command for SaQuit {
|
|||
}
|
||||
}
|
||||
|
||||
/// CHGNAME — change another user's real name (InspIRCd `m_chgname`). The oper-driven
|
||||
/// counterpart to SETNAME; broadcast to `setname`-capable peers so clients update live.
|
||||
/// CHGNAME — change another user's real name (the oper-driven counterpart to
|
||||
/// SETNAME); broadcast to `setname`-capable peers so clients update live.
|
||||
struct ChgName;
|
||||
impl Command for ChgName {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1187,8 +1187,8 @@ impl Command for ChgName {
|
|||
}
|
||||
}
|
||||
|
||||
/// CLEARCHAN — kick every user out of a channel (InspIRCd `m_clearchan`). Each
|
||||
/// removal is a normal KICK, propagated like SAKICK.
|
||||
/// CLEARCHAN — kick every user out of a channel. Each removal is a normal KICK,
|
||||
/// propagated like SAKICK.
|
||||
struct ClearChan;
|
||||
impl Command for ClearChan {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1244,7 +1244,7 @@ impl Command for ClearChan {
|
|||
}
|
||||
}
|
||||
|
||||
/// CHECK — oper diagnostic dump for a nick or channel (InspIRCd `m_check`).
|
||||
/// CHECK — oper diagnostic dump for a nick or channel.
|
||||
struct Check;
|
||||
impl Command for Check {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1329,8 +1329,8 @@ impl Command for Check {
|
|||
}
|
||||
}
|
||||
|
||||
/// SWHOIS — attach (or clear) an extra WHOIS line on a user (InspIRCd `m_swhois`).
|
||||
/// `SWHOIS <nick> :<text>`; an empty text removes it. Shown as RPL_WHOISSPECIAL.
|
||||
/// SWHOIS — attach (or clear) an extra WHOIS line on a user. `SWHOIS <nick>
|
||||
/// :<text>`; an empty text removes it. Shown as RPL_WHOISSPECIAL.
|
||||
struct SwhoisCmd;
|
||||
impl Command for SwhoisCmd {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1361,8 +1361,8 @@ impl Command for SwhoisCmd {
|
|||
}
|
||||
}
|
||||
|
||||
/// SETIDLE — reset your own idle time (InspIRCd `m_setidle`). `SETIDLE <seconds>`
|
||||
/// backdates the last-activity clock so WHOIS shows that idle time.
|
||||
/// SETIDLE — reset your own idle time. `SETIDLE <seconds>` backdates the
|
||||
/// last-activity clock so WHOIS shows that idle time.
|
||||
struct SetIdle;
|
||||
impl Command for SetIdle {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -1384,8 +1384,8 @@ impl Command for SetIdle {
|
|||
}
|
||||
}
|
||||
|
||||
/// ALLTIME — show the current server time to the requesting oper (InspIRCd
|
||||
/// `m_alltime`; on a single server there's just the one time to report).
|
||||
/// ALLTIME — show the current server time to the requesting oper (on a single
|
||||
/// server there's just the one time to report).
|
||||
struct AllTime;
|
||||
impl Command for AllTime {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
//! core_rehash — the REHASH command. Re-reads the config file and applies every
|
||||
//! setting that can change at runtime, the way InspIRCd's rehash does:
|
||||
//!
|
||||
//! * opers only; replies with RPL_REHASHING (382) and a server-notice to +s opers;
|
||||
//! * takes an optional `<servermask>` (we only rehash if it matches this server —
|
||||
//! there's no remote-rehash over S2S yet);
|
||||
//! * **keeps the running config if the file can't be read** (via `Config::try_load`),
|
||||
//! so a REHASH of a deleted/renamed config never resets opers/cloak-key to defaults.
|
||||
//! REHASH: re-read the config file and apply every setting that can change at
|
||||
//! runtime (opers only; replies RPL_REHASHING 382). Takes an optional
|
||||
//! `<servermask>`, matched against this server's name (no remote rehash over S2S).
|
||||
//! A missing/unreadable config file leaves the running config intact (via
|
||||
//! `Config::try_load`), so opers/cloak-key are never reset to defaults.
|
||||
//!
|
||||
//! Reloadable live: MOTD, oper blocks, cloak key, +G censor words, antimixedutf8,
|
||||
//! and the reverse-DNS options. Listener/bind/SID changes still need a restart.
|
||||
|
|
@ -50,8 +47,7 @@ impl Command for Rehash {
|
|||
let path = s.conf_path.clone();
|
||||
match Config::try_load(&path) {
|
||||
Some(fresh) => {
|
||||
// echoIRCd's own announcement (not InspIRCd's) — broadcast to
|
||||
// everyone connected, not just opers.
|
||||
// announce to everyone connected, not just opers
|
||||
s.announce(&format!(
|
||||
"admin {who} has changed the configuration of the server."
|
||||
));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
}
|
||||
|
||||
/// VHOST — claim a self-service virtual host with `VHOST <user> <pass>` matching a
|
||||
/// configured `vhost = <user> <pass> <host>` block (InspIRCd `m_vhost`).
|
||||
/// configured `vhost = <user> <pass> <host>` block.
|
||||
struct Vhost;
|
||||
impl Command for Vhost {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -247,10 +247,10 @@ fn cap_target(s: &Server, uid: Uid) -> String {
|
|||
.unwrap_or_else(|| "*".to_string())
|
||||
}
|
||||
|
||||
/// AUTHENTICATE — the SASL handshake. echoIRCd verifies nothing itself (it has no
|
||||
/// AUTHENTICATE — the SASL handshake. The ircd verifies nothing itself (it has no
|
||||
/// accounts); once a services server is linked over S2S the payload is relayed to
|
||||
/// it and `set_login` applied on success. Until then — exactly like InspIRCd with
|
||||
/// no services — SASL fails cleanly.
|
||||
/// it and `set_login` applied on success. With no services linked, SASL fails
|
||||
/// cleanly.
|
||||
struct Authenticate;
|
||||
impl Command for Authenticate {
|
||||
fn name(&self) -> &'static str {
|
||||
|
|
@ -274,7 +274,7 @@ impl Command for Authenticate {
|
|||
let arg = ¶ms[0];
|
||||
let mech = s.users.get(&uid).and_then(|u| u.sasl_mech.clone());
|
||||
// SASL is relayed to a linked services server (see `Server::sasl_relay`);
|
||||
// with none configured/linked it fails cleanly, exactly like InspIRCd.
|
||||
// with none configured/linked it fails cleanly.
|
||||
let have_services = s.sasl_link().is_some();
|
||||
match mech {
|
||||
// step 1 — the client picks a mechanism
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! core_watch — WATCH, MONITOR (IRCv3) and SILENCE. The per-user lists live on
|
||||
//! the `User`; the online/offline notifications are driven from the lifecycle
|
||||
//! code via [`crate::server::Server::watch_notify_online`] / `_offline`. Mirrors
|
||||
//! InspIRCd's `m_watch` / `m_monitor` / `m_silence`.
|
||||
//! WATCH, MONITOR (IRCv3), SILENCE and ACCEPT. The per-user lists live on the
|
||||
//! `User`; online/offline notifications are driven from the lifecycle code via
|
||||
//! [`crate::server::Server::watch_notify_online`] / `_offline`.
|
||||
|
||||
use crate::channels::normalize_mask;
|
||||
use crate::command::{CmdResult, Command};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
//! The built-in commands, grouped the way InspIRCd groups its `coremods/`:
|
||||
//! `core_user`, `core_channel`, `core_message`, `core_mode`, `core_oper`,
|
||||
//! `core_info`. Each module exposes `commands()`; [`command_table`] assembles the
|
||||
//! registry the core dispatches through.
|
||||
//! Built-in commands. Each module exposes `commands()`; [`command_table`]
|
||||
//! assembles the registry the core dispatches through.
|
||||
|
||||
pub mod core_channel;
|
||||
pub mod core_extra;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue