Compare commits
4 commits
alpine-pac
...
JadedBlueE
Author | SHA1 | Date | |
---|---|---|---|
|
8cf8af723d | ||
|
5fdb33e2c0 | ||
|
81a797945b | ||
|
371103fb35 |
19 changed files with 127 additions and 96 deletions
|
@ -1160,6 +1160,8 @@
|
|||
# Vector list of servers that conduwuit will refuse to download remote
|
||||
# media from.
|
||||
#
|
||||
# This is in addition to `forbidden_remote_server_names`.
|
||||
#
|
||||
#prevent_media_downloads_from = []
|
||||
|
||||
# List of forbidden server names that we will block incoming AND outgoing
|
||||
|
@ -1169,14 +1171,24 @@
|
|||
# sender user's server name, inbound federation X-Matrix origin, and
|
||||
# outbound federation handler.
|
||||
#
|
||||
# Additionally, it will hide messages from these servers for all users
|
||||
# on this server.
|
||||
#
|
||||
# Basically "global" ACLs.
|
||||
#
|
||||
#forbidden_remote_server_names = []
|
||||
|
||||
# The inverse of `forbidden_remote_server_names`. By default, allows all
|
||||
# servers. `forbidden_remote_server_names` takes precedence.
|
||||
#
|
||||
#allowed_remote_server_names = []
|
||||
|
||||
# List of forbidden server names that we will block all outgoing federated
|
||||
# room directory requests for. Useful for preventing our users from
|
||||
# wandering into bad servers or spaces.
|
||||
#
|
||||
# This is in addition to `forbidden_remote_server_names`.
|
||||
#
|
||||
#forbidden_remote_room_directory_server_names = []
|
||||
|
||||
# Vector list of IPv4 and IPv6 CIDR ranges / subnets *in quotes* that you
|
||||
|
|
|
@ -45,6 +45,7 @@ pub(crate) async fn get_public_rooms_filtered_route(
|
|||
.config
|
||||
.forbidden_remote_room_directory_server_names
|
||||
.contains(server)
|
||||
|| services.moderation.is_remote_server_forbidden(server)
|
||||
{
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
}
|
||||
|
@ -87,6 +88,7 @@ pub(crate) async fn get_public_rooms_route(
|
|||
.config
|
||||
.forbidden_remote_room_directory_server_names
|
||||
.contains(server)
|
||||
|| services.moderation.is_remote_server_forbidden(server)
|
||||
{
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
}
|
||||
|
|
|
@ -71,10 +71,8 @@ async fn banned_room_check(
|
|||
if let Some(room_id) = room_id {
|
||||
if services.rooms.metadata.is_banned(room_id).await
|
||||
|| services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&room_id.server_name().unwrap().to_owned())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(room_id.server_name().unwrap())
|
||||
{
|
||||
warn!(
|
||||
"User {user_id} who is not an admin attempted to send an invite for or \
|
||||
|
@ -111,12 +109,7 @@ async fn banned_room_check(
|
|||
return Err!(Request(Forbidden("This room is banned on this homeserver.")));
|
||||
}
|
||||
} else if let Some(server_name) = server_name {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server_name.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server_name) {
|
||||
warn!(
|
||||
"User {user_id} who is not an admin tried joining a room which has the server \
|
||||
name {server_name} that is globally forbidden. Rejecting.",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use axum::extract::State;
|
||||
use conduwuit::{
|
||||
at, is_equal_to,
|
||||
at,
|
||||
utils::{
|
||||
result::{FlatOk, LogErr},
|
||||
stream::{BroadbandExt, TryIgnore, WidebandExt},
|
||||
|
@ -241,11 +241,8 @@ pub(crate) async fn ignored_filter(
|
|||
if IGNORED_MESSAGE_TYPES.binary_search(&pdu.kind).is_ok()
|
||||
&& (services.users.user_is_ignored(&pdu.sender, user_id).await
|
||||
|| services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.iter()
|
||||
.any(is_equal_to!(pdu.sender().server_name())))
|
||||
.moderation
|
||||
.is_remote_server_forbidden(pdu.sender().server_name()))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -317,12 +317,7 @@ fn auth_server_checks(services: &Services, x_matrix: &XMatrix) -> Result<()> {
|
|||
}
|
||||
|
||||
let origin = &x_matrix.origin;
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(origin)
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(origin) {
|
||||
return Err!(Request(Forbidden(debug_warn!(
|
||||
"Federation requests from {origin} denied."
|
||||
))));
|
||||
|
|
|
@ -36,21 +36,14 @@ pub(crate) async fn create_invite_route(
|
|||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
}
|
||||
}
|
||||
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
warn!(
|
||||
"Received federated/remote invite from banned server {} for room ID {}. Rejecting.",
|
||||
|
|
|
@ -42,10 +42,8 @@ pub(crate) async fn create_join_event_template_route(
|
|||
.await?;
|
||||
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
warn!(
|
||||
"Server {} for remote user {} tried joining room ID {} which has a server name that \
|
||||
|
@ -58,12 +56,7 @@ pub(crate) async fn create_join_event_template_route(
|
|||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
return Err!(Request(Forbidden(warn!(
|
||||
"Room ID server name {server} is banned on this homeserver."
|
||||
))));
|
||||
|
|
|
@ -34,10 +34,8 @@ pub(crate) async fn create_knock_event_template_route(
|
|||
.await?;
|
||||
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
warn!(
|
||||
"Server {} for remote user {} tried knocking room ID {} which has a server name \
|
||||
|
@ -50,12 +48,7 @@ pub(crate) async fn create_knock_event_template_route(
|
|||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -270,10 +270,8 @@ pub(crate) async fn create_join_event_v1_route(
|
|||
body: Ruma<create_join_event::v1::Request>,
|
||||
) -> Result<create_join_event::v1::Response> {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
warn!(
|
||||
"Server {} tried joining room ID {} through us who has a server name that is \
|
||||
|
@ -285,12 +283,7 @@ pub(crate) async fn create_join_event_v1_route(
|
|||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
warn!(
|
||||
"Server {} tried joining room ID {} through us which has a server name that is \
|
||||
globally forbidden. Rejecting.",
|
||||
|
@ -318,21 +311,14 @@ pub(crate) async fn create_join_event_v2_route(
|
|||
body: Ruma<create_join_event::v2::Request>,
|
||||
) -> Result<create_join_event::v2::Response> {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
return Err!(Request(Forbidden("Server is banned on this homeserver.")));
|
||||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
warn!(
|
||||
"Server {} tried joining room ID {} through us which has a server name that is \
|
||||
globally forbidden. Rejecting.",
|
||||
|
|
|
@ -22,10 +22,8 @@ pub(crate) async fn create_knock_event_v1_route(
|
|||
body: Ruma<send_knock::v1::Request>,
|
||||
) -> Result<send_knock::v1::Response> {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(body.origin())
|
||||
.moderation
|
||||
.is_remote_server_forbidden(body.origin())
|
||||
{
|
||||
warn!(
|
||||
"Server {} tried knocking room ID {} who has a server name that is globally \
|
||||
|
@ -37,12 +35,7 @@ pub(crate) async fn create_knock_event_v1_route(
|
|||
}
|
||||
|
||||
if let Some(server) = body.room_id.server_name() {
|
||||
if services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(&server.to_owned())
|
||||
{
|
||||
if services.moderation.is_remote_server_forbidden(server) {
|
||||
warn!(
|
||||
"Server {} tried knocking room ID {} which has a server name that is globally \
|
||||
forbidden. Rejecting.",
|
||||
|
|
|
@ -1324,6 +1324,8 @@ pub struct Config {
|
|||
/// Vector list of servers that conduwuit will refuse to download remote
|
||||
/// media from.
|
||||
///
|
||||
/// This is in addition to `forbidden_remote_server_names`.
|
||||
///
|
||||
/// default: []
|
||||
#[serde(default)]
|
||||
pub prevent_media_downloads_from: HashSet<OwnedServerName>,
|
||||
|
@ -1335,16 +1337,28 @@ pub struct Config {
|
|||
/// sender user's server name, inbound federation X-Matrix origin, and
|
||||
/// outbound federation handler.
|
||||
///
|
||||
/// Additionally, it will hide messages from these servers for all users
|
||||
/// on this server.
|
||||
///
|
||||
/// Basically "global" ACLs.
|
||||
///
|
||||
/// default: []
|
||||
#[serde(default)]
|
||||
pub forbidden_remote_server_names: HashSet<OwnedServerName>,
|
||||
|
||||
/// The inverse of `forbidden_remote_server_names`. By default, allows all
|
||||
/// servers. `forbidden_remote_server_names` takes precedence.
|
||||
///
|
||||
/// default: []
|
||||
#[serde(default)]
|
||||
pub allowed_remote_server_names: HashSet<OwnedServerName>,
|
||||
|
||||
/// List of forbidden server names that we will block all outgoing federated
|
||||
/// room directory requests for. Useful for preventing our users from
|
||||
/// wandering into bad servers or spaces.
|
||||
///
|
||||
/// This is in addition to `forbidden_remote_server_names`.
|
||||
///
|
||||
/// default: []
|
||||
#[serde(default = "HashSet::new")]
|
||||
pub forbidden_remote_room_directory_server_names: HashSet<OwnedServerName>,
|
||||
|
@ -1871,7 +1885,7 @@ impl Config {
|
|||
let mut addrs = Vec::with_capacity(
|
||||
self.get_bind_hosts()
|
||||
.len()
|
||||
.saturating_add(self.get_bind_ports().len()),
|
||||
.saturating_mul(self.get_bind_ports().len()),
|
||||
);
|
||||
for host in &self.get_bind_hosts() {
|
||||
for port in &self.get_bind_ports() {
|
||||
|
|
|
@ -65,13 +65,7 @@ where
|
|||
return Err!(Config("allow_federation", "Federation is disabled."));
|
||||
}
|
||||
|
||||
if self
|
||||
.services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(dest)
|
||||
{
|
||||
if self.services.moderation.is_remote_server_forbidden(dest) {
|
||||
return Err!(Request(Forbidden(debug_warn!("Federation with {dest} is not allowed."))));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||
|
||||
use conduwuit::{Result, Server};
|
||||
|
||||
use crate::{client, resolver, server_keys, Dep};
|
||||
use crate::{client, moderation, resolver, server_keys, Dep};
|
||||
|
||||
pub struct Service {
|
||||
services: Services,
|
||||
|
@ -15,6 +15,7 @@ struct Services {
|
|||
client: Dep<client::Service>,
|
||||
resolver: Dep<resolver::Service>,
|
||||
server_keys: Dep<server_keys::Service>,
|
||||
moderation: Dep<moderation::Service>,
|
||||
}
|
||||
|
||||
impl crate::Service for Service {
|
||||
|
@ -25,6 +26,7 @@ impl crate::Service for Service {
|
|||
client: args.depend::<client::Service>("client"),
|
||||
resolver: args.depend::<resolver::Service>("resolver"),
|
||||
server_keys: args.depend::<server_keys::Service>("server_keys"),
|
||||
moderation: args.depend::<moderation::Service>("moderation"),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use tokio::{
|
|||
|
||||
use self::data::{Data, Metadata};
|
||||
pub use self::thumbnail::Dim;
|
||||
use crate::{client, globals, sending, Dep};
|
||||
use crate::{client, globals, moderation, sending, Dep};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FileMeta {
|
||||
|
@ -42,6 +42,7 @@ struct Services {
|
|||
client: Dep<client::Service>,
|
||||
globals: Dep<globals::Service>,
|
||||
sending: Dep<sending::Service>,
|
||||
moderation: Dep<moderation::Service>,
|
||||
}
|
||||
|
||||
/// generated MXC ID (`media-id`) length
|
||||
|
@ -64,6 +65,7 @@ impl crate::Service for Service {
|
|||
client: args.depend::<client::Service>("client"),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
sending: args.depend::<sending::Service>("sending"),
|
||||
moderation: args.depend::<moderation::Service>("moderation"),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -427,6 +427,10 @@ fn check_fetch_authorized(&self, mxc: &Mxc<'_>) -> Result<()> {
|
|||
.config
|
||||
.prevent_media_downloads_from
|
||||
.contains(mxc.server_name)
|
||||
|| self
|
||||
.services
|
||||
.moderation
|
||||
.is_remote_server_forbidden(mxc.server_name)
|
||||
{
|
||||
// we'll lie to the client and say the blocked server's media was not found and
|
||||
// log. the client has no way of telling anyways so this is a security bonus.
|
||||
|
|
|
@ -15,6 +15,7 @@ pub mod federation;
|
|||
pub mod globals;
|
||||
pub mod key_backups;
|
||||
pub mod media;
|
||||
pub mod moderation;
|
||||
pub mod presence;
|
||||
pub mod pusher;
|
||||
pub mod resolver;
|
||||
|
|
54
src/service/moderation/mod.rs
Normal file
54
src/service/moderation/mod.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use conduwuit::{implement, Result, Server};
|
||||
use ruma::ServerName;
|
||||
|
||||
use crate::{globals, Dep};
|
||||
|
||||
pub struct Service {
|
||||
services: Services,
|
||||
}
|
||||
|
||||
struct Services {
|
||||
pub server: Arc<Server>,
|
||||
pub globals: Dep<globals::Service>,
|
||||
}
|
||||
|
||||
impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(Self {
|
||||
services: Services {
|
||||
server: args.server.clone(),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||
}
|
||||
|
||||
#[implement(Service)]
|
||||
#[must_use]
|
||||
pub fn is_remote_server_forbidden(&self, server_name: &ServerName) -> bool {
|
||||
// Forbidden if NOT (allowed is empty OR allowed contains server OR is self)
|
||||
// OR forbidden contains server
|
||||
!(self
|
||||
.services
|
||||
.server
|
||||
.config
|
||||
.allowed_remote_server_names
|
||||
.is_empty()
|
||||
|| self
|
||||
.services
|
||||
.server
|
||||
.config
|
||||
.allowed_remote_server_names
|
||||
.contains(server_name)
|
||||
|| server_name == self.services.globals.server_name())
|
||||
|| self
|
||||
.services
|
||||
.server
|
||||
.config
|
||||
.forbidden_remote_server_names
|
||||
.contains(server_name)
|
||||
}
|
|
@ -30,8 +30,9 @@ pub use self::{
|
|||
sender::{EDU_LIMIT, PDU_LIMIT},
|
||||
};
|
||||
use crate::{
|
||||
account_data, client, federation, globals, presence, pusher, rooms,
|
||||
rooms::timeline::RawPduId, users, Dep,
|
||||
account_data, client, federation, globals, presence, pusher,
|
||||
rooms::{self, timeline::RawPduId},
|
||||
users, Dep,
|
||||
};
|
||||
|
||||
pub struct Service {
|
||||
|
|
|
@ -12,8 +12,8 @@ use tokio::sync::Mutex;
|
|||
use crate::{
|
||||
account_data, admin, appservice, client, config, emergency, federation, globals, key_backups,
|
||||
manager::Manager,
|
||||
media, presence, pusher, resolver, rooms, sending, server_keys, service,
|
||||
service::{Args, Map, Service},
|
||||
media, moderation, presence, pusher, resolver, rooms, sending, server_keys,
|
||||
service::{self, Args, Map, Service},
|
||||
sync, transaction_ids, uiaa, updates, users,
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,7 @@ pub struct Services {
|
|||
pub pusher: Arc<pusher::Service>,
|
||||
pub resolver: Arc<resolver::Service>,
|
||||
pub rooms: rooms::Service,
|
||||
pub moderation: Arc<moderation::Service>,
|
||||
pub federation: Arc<federation::Service>,
|
||||
pub sending: Arc<sending::Service>,
|
||||
pub server_keys: Arc<server_keys::Service>,
|
||||
|
@ -98,6 +99,7 @@ impl Services {
|
|||
typing: build!(rooms::typing::Service),
|
||||
user: build!(rooms::user::Service),
|
||||
},
|
||||
moderation: build!(moderation::Service),
|
||||
federation: build!(federation::Service),
|
||||
sending: build!(sending::Service),
|
||||
server_keys: build!(server_keys::Service),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue