diff --git a/src/service/client/mod.rs b/src/service/client/mod.rs index f9a89e99..2794efc1 100644 --- a/src/service/client/mod.rs +++ b/src/service/client/mod.rs @@ -1,6 +1,7 @@ use std::{sync::Arc, time::Duration}; -use conduit::{Config, Result}; +use conduit::{err, implement, trace, Config, Result}; +use ipaddress::IPAddress; use reqwest::redirect; use crate::{resolver, service}; @@ -15,6 +16,8 @@ pub struct Service { pub sender: reqwest::Client, pub appservice: reqwest::Client, pub pusher: reqwest::Client, + + pub cidr_range_denylist: Vec, } impl crate::Service for Service { @@ -86,6 +89,14 @@ impl crate::Service for Service { .pool_idle_timeout(Duration::from_secs(config.pusher_idle_timeout)) .redirect(redirect::Policy::limited(2)) .build()?, + + cidr_range_denylist: config + .ip_range_denylist + .iter() + .map(IPAddress::parse) + .inspect(|cidr| trace!("Denied CIDR range: {cidr:?}")) + .collect::>() + .map_err(|e| err!(Config("ip_range_denylist", e)))?, })) } @@ -152,3 +163,12 @@ fn base(config: &Config) -> Result { Ok(builder) } } + +#[inline] +#[must_use] +#[implement(Service)] +pub fn valid_cidr_range(&self, ip: &IPAddress) -> bool { + self.cidr_range_denylist + .iter() + .all(|cidr| !cidr.includes(ip)) +} diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 3eefe4b7..4fb1ce2d 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -7,9 +7,8 @@ use std::{ time::Instant, }; -use conduit::{err, error, trace, Config, Result}; +use conduit::{error, Config, Result}; use data::Data; -use ipaddress::IPAddress; use regex::RegexSet; use ruma::{ OwnedEventId, OwnedRoomAliasId, OwnedServerName, OwnedUserId, RoomAliasId, RoomVersionId, ServerName, UserId, @@ -22,7 +21,6 @@ pub struct Service { pub db: Data, pub config: Config, - pub cidr_range_denylist: Vec, jwt_decoding_key: Option, pub stable_room_versions: Vec, pub unstable_room_versions: Vec, @@ -59,14 +57,6 @@ impl crate::Service for Service { // Experimental, partially supported room versions let unstable_room_versions = vec![RoomVersionId::V2, RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5]; - let cidr_range_denylist: Vec<_> = config - .ip_range_denylist - .iter() - .map(IPAddress::parse) - .inspect(|cidr| trace!("Denied CIDR range: {cidr:?}")) - .collect::>() - .map_err(|e| err!(Config("ip_range_denylist", e)))?; - let turn_secret = config .turn_secret_file .as_ref() @@ -95,7 +85,6 @@ impl crate::Service for Service { let mut s = Self { db, config: config.clone(), - cidr_range_denylist, jwt_decoding_key, stable_room_versions, unstable_room_versions, @@ -255,17 +244,6 @@ impl Service { } } - #[inline] - pub fn valid_cidr_range(&self, ip: &IPAddress) -> bool { - for cidr in &self.cidr_range_denylist { - if cidr.includes(ip) { - return false; - } - } - - true - } - /// checks if `user_id` is local to us via server_name comparison #[inline] pub fn user_is_local(&self, user_id: &UserId) -> bool { self.server_is_ours(user_id.server_name()) } diff --git a/src/service/media/preview.rs b/src/service/media/preview.rs index acc9d8ed..eb9be560 100644 --- a/src/service/media/preview.rs +++ b/src/service/media/preview.rs @@ -87,7 +87,7 @@ pub async fn get_url_preview(&self, url: &Url) -> Result { #[implement(Service)] async fn request_url_preview(&self, url: &Url) -> Result { if let Ok(ip) = IPAddress::parse(url.host_str().expect("URL previously validated")) { - if !self.services.globals.valid_cidr_range(&ip) { + if !self.services.client.valid_cidr_range(&ip) { return Err!(BadServerResponse("Requesting from this address is forbidden")); } } @@ -97,7 +97,7 @@ async fn request_url_preview(&self, url: &Url) -> Result { if let Some(remote_addr) = response.remote_addr() { if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { - if !self.services.globals.valid_cidr_range(&ip) { + if !self.services.client.valid_cidr_range(&ip) { return Err!(BadServerResponse("Requesting from this address is forbidden")); } } diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 6b02c7f8..df5852c6 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -151,7 +151,7 @@ impl Service { if let Some(url_host) = reqwest_request.url().host_str() { trace!("Checking request URL for IP"); if let Ok(ip) = IPAddress::parse(url_host) { - if !self.services.globals.valid_cidr_range(&ip) { + if !self.services.client.valid_cidr_range(&ip) { return Err!(BadServerResponse("Not allowed to send requests to this IP")); } } @@ -166,7 +166,7 @@ impl Service { trace!("Checking response destination's IP"); if let Some(remote_addr) = response.remote_addr() { if let Ok(ip) = IPAddress::parse(remote_addr.ip().to_string()) { - if !self.services.globals.valid_cidr_range(&ip) { + if !self.services.client.valid_cidr_range(&ip) { return Err!(BadServerResponse("Not allowed to send requests to this IP")); } } diff --git a/src/service/resolver/actual.rs b/src/service/resolver/actual.rs index 6589a58b..8553e8bb 100644 --- a/src/service/resolver/actual.rs +++ b/src/service/resolver/actual.rs @@ -358,7 +358,7 @@ impl super::Service { } pub(crate) fn validate_ip(&self, ip: &IPAddress) -> Result<()> { - if !self.services.globals.valid_cidr_range(ip) { + if !self.services.client.valid_cidr_range(ip) { return Err!(BadServerResponse("Not allowed to send requests to this IP")); } diff --git a/src/service/resolver/mod.rs b/src/service/resolver/mod.rs index 28b7063d..111de292 100644 --- a/src/service/resolver/mod.rs +++ b/src/service/resolver/mod.rs @@ -9,7 +9,7 @@ use std::{fmt::Write, sync::Arc}; use conduit::{Result, Server}; use self::{cache::Cache, dns::Resolver}; -use crate::{client, globals, Dep}; +use crate::{client, Dep}; pub struct Service { pub cache: Arc, @@ -20,7 +20,6 @@ pub struct Service { struct Services { server: Arc, client: Dep, - globals: Dep, } impl crate::Service for Service { @@ -33,7 +32,6 @@ impl crate::Service for Service { services: Services { server: args.server.clone(), client: args.depend::("client"), - globals: args.depend::("globals"), }, })) }