webirc: restrict a gateway password to a source ip-mask; document webirc in the example config
This commit is contained in:
parent
6a634ef678
commit
49a1bf08b9
4 changed files with 26 additions and 13 deletions
|
|
@ -29,6 +29,11 @@ bind_server = 0.0.0.0:7000
|
||||||
# TLS with a client certificate (its fingerprint is sent to services).
|
# TLS with a client certificate (its fingerprint is sent to services).
|
||||||
# sasl_server = services.example.net
|
# sasl_server = services.example.net
|
||||||
|
|
||||||
|
# trusted web gateways (CGI:IRC / kiwiirc-style): they send WEBIRC to declare the
|
||||||
|
# real client's host+ip. webirc = <password> [gateway-name] [ip-mask]; the ip-mask
|
||||||
|
# restricts which source IP may use the password (recommended). Repeat for more.
|
||||||
|
# webirc = CHANGE_THIS_WEBIRC_SECRET mygateway 203.0.113.9
|
||||||
|
|
||||||
# IRC operators — oper = <name> <password>
|
# IRC operators — oper = <name> <password>
|
||||||
oper = admin CHANGE_THIS_PASSWORD
|
oper = admin CHANGE_THIS_PASSWORD
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,13 @@ pub struct Config {
|
||||||
pub tls_cert: Option<String>, // PEM certificate chain
|
pub tls_cert: Option<String>, // PEM certificate chain
|
||||||
pub tls_key: Option<String>, // PEM private key
|
pub tls_key: Option<String>, // PEM private key
|
||||||
pub motd: Vec<String>,
|
pub motd: Vec<String>,
|
||||||
pub opers: Vec<(String, String)>, // (name, password)
|
pub opers: Vec<(String, String)>, // (name, password)
|
||||||
pub cloak_key: Option<String>, // secret key for host cloaking (+x); None = off
|
pub cloak_key: Option<String>, // secret key for host cloaking (+x); None = off
|
||||||
pub sid: String, // this server's 3-char server id (S2S)
|
pub sid: String, // this server's 3-char server id (S2S)
|
||||||
pub serverdesc: String, // this server's description
|
pub serverdesc: String, // this server's description
|
||||||
pub bind_server: Option<String>, // the server-to-server link listener
|
pub bind_server: Option<String>, // the server-to-server link listener
|
||||||
pub links: Vec<LinkBlock>, // peers we accept / dial
|
pub links: Vec<LinkBlock>, // peers we accept / dial
|
||||||
pub conf_path: String, // where this was loaded from (for REHASH)
|
pub conf_path: String, // where this was loaded from (for REHASH)
|
||||||
pub censor: Vec<(String, String)>, // +G bad words: (find, replace); empty replace = block
|
pub censor: Vec<(String, String)>, // +G bad words: (find, replace); empty replace = block
|
||||||
pub amu: AntiMixedCfg, // antimixedutf8 module config
|
pub amu: AntiMixedCfg, // antimixedutf8 module config
|
||||||
pub resolve_hosts: bool, // reverse-DNS clients on connect (default on)
|
pub resolve_hosts: bool, // reverse-DNS clients on connect (default on)
|
||||||
|
|
@ -75,7 +75,7 @@ pub struct Config {
|
||||||
pub dnsbl_action: String, // mark | kline | gline | zline (on a hit)
|
pub dnsbl_action: String, // mark | kline | gline | zline (on a hit)
|
||||||
pub dnsbl_reason: String, // ban reason for a DNSBL hit
|
pub dnsbl_reason: String, // ban reason for a DNSBL hit
|
||||||
pub sasl_server: String, // linked services server that handles SASL ("" = none)
|
pub sasl_server: String, // linked services server that handles SASL ("" = none)
|
||||||
pub webirc: Vec<(String, String)>, // trusted web gateways: (password, gateway name)
|
pub webirc: Vec<(String, String, String)>, // web gateways: (password, name, ip-mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
|
@ -238,11 +238,12 @@ impl Config {
|
||||||
"dnsbl_reason" => c.dnsbl_reason = v.to_string(),
|
"dnsbl_reason" => c.dnsbl_reason = v.to_string(),
|
||||||
"sasl_server" | "sasl_target" => c.sasl_server = v.to_string(),
|
"sasl_server" | "sasl_target" => c.sasl_server = v.to_string(),
|
||||||
"webirc" => {
|
"webirc" => {
|
||||||
// webirc = <password> [gateway-name]
|
// webirc = <password> [gateway-name] [ip-mask]
|
||||||
let mut it = v.split_whitespace();
|
let mut it = v.split_whitespace();
|
||||||
if let Some(pass) = it.next() {
|
if let Some(pass) = it.next() {
|
||||||
let gw = it.next().unwrap_or("webirc").to_string();
|
let gw = it.next().unwrap_or("webirc").to_string();
|
||||||
c.webirc.push((pass.to_string(), gw));
|
let mask = it.next().unwrap_or("").to_string();
|
||||||
|
c.webirc.push((pass.to_string(), gw, mask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
|
|
||||||
|
use crate::channels::glob_match;
|
||||||
use crate::command::{CmdResult, Command};
|
use crate::command::{CmdResult, Command};
|
||||||
use crate::numeric::*;
|
use crate::numeric::*;
|
||||||
use crate::server::Server;
|
use crate::server::Server;
|
||||||
|
|
@ -45,11 +46,17 @@ impl Command for WebIrc {
|
||||||
return CmdResult::Fail; // can't re-spoof a registered session
|
return CmdResult::Fail; // can't re-spoof a registered session
|
||||||
}
|
}
|
||||||
let (pass, host, ip) = (¶ms[0], ¶ms[2], ¶ms[3]);
|
let (pass, host, ip) = (¶ms[0], ¶ms[2], ¶ms[3]);
|
||||||
|
// the gateway's own connecting IP (before we spoof it below)
|
||||||
|
let from = s
|
||||||
|
.users
|
||||||
|
.get(&uid)
|
||||||
|
.map(|u| u.addr.ip().to_string())
|
||||||
|
.unwrap_or_default();
|
||||||
let Some(gw) = s
|
let Some(gw) = s
|
||||||
.webirc
|
.webirc
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(p, _)| p == pass)
|
.find(|(p, _, mask)| p == pass && (mask.is_empty() || glob_match(mask, &from)))
|
||||||
.map(|(_, g)| g.clone())
|
.map(|(_, g, _)| g.clone())
|
||||||
else {
|
else {
|
||||||
s.notice_star(uid, "WEBIRC: invalid credentials");
|
s.notice_star(uid, "WEBIRC: invalid credentials");
|
||||||
return CmdResult::Fail;
|
return CmdResult::Fail;
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ pub struct Server {
|
||||||
pub dnsbl_action: String, // mark | kline | gline | zline
|
pub dnsbl_action: String, // mark | kline | gline | zline
|
||||||
pub dnsbl_reason: String, // ban reason on a DNSBL hit
|
pub dnsbl_reason: String, // ban reason on a DNSBL hit
|
||||||
pub sasl_server: String, // services server that handles SASL
|
pub sasl_server: String, // services server that handles SASL
|
||||||
pub webirc: Vec<(String, String)>, // trusted web gateways: (password, name)
|
pub webirc: Vec<(String, String, String)>, // web gateways: (password, name, ip-mask)
|
||||||
// labeled-response: while Some((uid, buf)), that client's own responses are
|
// labeled-response: while Some((uid, buf)), that client's own responses are
|
||||||
// diverted into `buf` instead of the socket, so `on_line` can wrap them with
|
// diverted into `buf` instead of the socket, so `on_line` can wrap them with
|
||||||
// the command's `label` (single tag, BATCH, or ACK). RefCell because the
|
// the command's `label` (single tag, BATCH, or ACK). RefCell because the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue