From 423fc6dad02b7e2be61582f246dc2276ad53def0 Mon Sep 17 00:00:00 2001 From: Jason Volk <jason@zemos.net> Date: Sun, 21 Apr 2024 22:32:45 -0700 Subject: [PATCH] precompute cidr range denylist; move validator. Signed-off-by: Jason Volk <jason@zemos.net> --- src/service/globals/mod.rs | 22 +++++++++++++++++++++- src/service/sending/send.rs | 13 ++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 874ba22ed..1aea4e32b 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -14,6 +14,7 @@ use base64::{engine::general_purpose, Engine as _}; pub use data::Data; use hickory_resolver::TokioAsyncResolver; +use ipaddress::IPAddress; use regex::RegexSet; use ruma::{ api::{ @@ -25,7 +26,7 @@ RoomVersionId, ServerName, UserId, }; use tokio::sync::{broadcast, watch::Receiver, Mutex, RwLock, Semaphore}; -use tracing::{error, info}; +use tracing::{error, info, trace}; use tracing_subscriber::{EnvFilter, Registry}; use url::Url; @@ -46,6 +47,7 @@ pub struct Service<'a> { pub tracing_reload_handle: tracing_subscriber::reload::Handle<EnvFilter, Registry>, pub config: Config, + pub cidr_range_denylist: Vec<IPAddress>, keypair: Arc<ruma::signatures::Ed25519KeyPair>, jwt_decoding_key: Option<jsonwebtoken::DecodingKey>, pub resolver: Arc<resolver::Resolver>, @@ -138,10 +140,18 @@ pub fn load( argon2::Params::new(19456, 2, 1, None).expect("valid parameters"), ); + let mut cidr_range_denylist = Vec::new(); + for cidr in config.ip_range_denylist.clone() { + let cidr = IPAddress::parse(cidr).expect("valid cidr range"); + trace!("Denied CIDR range: {:?}", cidr); + cidr_range_denylist.push(cidr); + } + let mut s = Self { tracing_reload_handle, db, config: config.clone(), + cidr_range_denylist, keypair: Arc::new(keypair), resolver: resolver.clone(), client: client::Client::new(config, &resolver), @@ -424,6 +434,16 @@ pub fn well_known_server(&self) -> &Option<OwnedServerName> { &self.config.well_ pub fn unix_socket_path(&self) -> &Option<PathBuf> { &self.config.unix_socket_path } + pub fn valid_cidr_range(&self, ip: &IPAddress) -> bool { + for cidr in &self.cidr_range_denylist { + if cidr.includes(ip) { + return false; + } + } + + true + } + pub fn shutdown(&self) { self.shutdown.store(true, atomic::Ordering::Relaxed); // On shutdown diff --git a/src/service/sending/send.rs b/src/service/sending/send.rs index 726ceffe3..d6bd36d2e 100644 --- a/src/service/sending/send.rs +++ b/src/service/sending/send.rs @@ -536,17 +536,8 @@ fn validate_destination_ip_literal(destination: &ServerName) -> Result<()> { } fn validate_ip(ip: &IPAddress) -> Result<()> { - let cidr_ranges_s = services().globals.ip_range_denylist().to_vec(); - let mut cidr_ranges: Vec<IPAddress> = Vec::new(); - for cidr in cidr_ranges_s { - cidr_ranges.push(IPAddress::parse(cidr).expect("we checked this at startup")); - } - - trace!("List of pushed CIDR ranges: {:?}", cidr_ranges); - for cidr in cidr_ranges { - if cidr.includes(ip) { - return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); - } + if !services().globals.valid_cidr_range(ip) { + return Err(Error::BadServerResponse("Not allowed to send requests to this IP")); } Ok(()) -- GitLab