don't send requests to specified list of IP CIDRs

this can most definitely be improved but this is a decent attempt.
the only annoying this is i couldn't just use a Vec<IPAddress> which
would have significantly simplified all of this, but serde can't
deserialise it on the config side i guess.

i may find a better way to do this in the future, but this should cover
most areas anyways.

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-01-21 22:59:06 -05:00 committed by June
parent 71d247232d
commit fa0c083555
8 changed files with 186 additions and 3 deletions

View file

@ -11,6 +11,7 @@ use futures_util::future::TryFutureExt;
use get_profile_information::v1::ProfileField;
use http::header::{HeaderValue, AUTHORIZATION};
use ipaddress::IPAddress;
use ruma::{
api::{
client::error::{Error as RumaError, ErrorKind},
@ -114,7 +115,6 @@ impl FedDest {
}
}
#[tracing::instrument(skip(request))]
pub(crate) async fn send_request<T: OutgoingRequest>(
destination: &ServerName,
request: T,
@ -132,6 +132,29 @@ where
));
}
if destination.is_ip_literal() {
info!("Destination is an IP literal, checking against IP range denylist.");
let ip = IPAddress::parse(destination.host()).map_err(|e| {
warn!("Failed to parse IP literal from string: {}", e);
Error::BadServerResponse("Invalid IP address")
})?;
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"));
}
for cidr in cidr_ranges {
if ip.includes(&cidr) {
return Err(Error::BadServerResponse(
"Not allowed to send requests to this IP",
));
}
}
}
debug!("Preparing to send request to {destination}");
let mut write_destination_to_cache = false;