From 4c30eec35503797ad8d1829308558b6166fdb8d4 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Thu, 19 Jun 2025 20:26:39 +0100 Subject: [PATCH 1/7] policy server following maybe??? (cherry picked from commit e1c06e10f6ce27b570682989fed0defda0fe09a1) --- Cargo.lock | 22 ++++---- Cargo.toml | 2 +- src/core/matrix/state_res/event_auth.rs | 7 +-- .../rooms/event_handler/call_policyserv.rs | 54 +++++++++++++++++++ src/service/rooms/event_handler/mod.rs | 1 + .../event_handler/upgrade_outlier_pdu.rs | 22 +++++--- 6 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 src/service/rooms/event_handler/call_policyserv.rs diff --git a/Cargo.lock b/Cargo.lock index ec6e848d..44c210f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3695,7 +3695,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "assign", "js_int", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.10.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "js_int", "ruma-common", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "as_variant", "assign", @@ -3750,7 +3750,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "as_variant", "base64 0.22.1", @@ -3782,7 +3782,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "as_variant", "indexmap 2.9.0", @@ -3807,7 +3807,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "bytes", "headers", @@ -3829,7 +3829,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "js_int", "thiserror 2.0.12", @@ -3838,7 +3838,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "js_int", "ruma-common", @@ -3848,7 +3848,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3863,7 +3863,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "js_int", "ruma-common", @@ -3875,7 +3875,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.15.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=d6870a7fb7f6cccff63f7fd0ff6c581bad80e983#d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" dependencies = [ "base64 0.22.1", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index af904447..2ad5c1ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -350,7 +350,7 @@ version = "0.1.2" [workspace.dependencies.ruma] git = "https://forgejo.ellis.link/continuwuation/ruwuma" #branch = "conduwuit-changes" -rev = "d6870a7fb7f6cccff63f7fd0ff6c581bad80e983" +rev = "781606d1fafbf2daa220fd354d9ad0479a308cd1" features = [ "compat", "rand", diff --git a/src/core/matrix/state_res/event_auth.rs b/src/core/matrix/state_res/event_auth.rs index 759ab5cb..bd2b9c61 100644 --- a/src/core/matrix/state_res/event_auth.rs +++ b/src/core/matrix/state_res/event_auth.rs @@ -5,7 +5,7 @@ use futures::{ future::{OptionFuture, join3}, }; use ruma::{ - Int, OwnedUserId, RoomVersionId, UserId, + EventId, Int, OwnedUserId, RoomVersionId, UserId, events::room::{ create::RoomCreateEventContent, join_rules::{JoinRule, RoomJoinRulesEventContent}, @@ -217,8 +217,9 @@ where } /* - // TODO: In the past this code caused problems federating with synapse, maybe this has been - // resolved already. Needs testing. + // TODO: In the past this code was commented as it caused problems with Synapse. This is no + // longer the case. This needs to be implemented. + // See also: https://github.com/ruma/ruma/pull/2064 // // 2. Reject if auth_events // a. auth_events cannot have duplicate keys since it's a BTree diff --git a/src/service/rooms/event_handler/call_policyserv.rs b/src/service/rooms/event_handler/call_policyserv.rs new file mode 100644 index 00000000..548a0081 --- /dev/null +++ b/src/service/rooms/event_handler/call_policyserv.rs @@ -0,0 +1,54 @@ +use conduwuit::{Err, Result, debug, implement, trace, warn}; +use ruma::{ + EventId, OwnedEventId, OwnedServerName, RoomId, ServerName, + api::federation::room::policy::v1::{Request as PolicyRequest, Response as PolicyResponse}, + events::{ + StateEventType, + room::{ + policy::{PolicyServerResponseContent, RoomPolicyEventContent}, + server_acl::RoomServerAclEventContent, + }, + }, +}; +use serde::{Deserialize, Serialize}; + +/// Returns Ok if the policy server allows the event +#[implement(super::Service)] +#[tracing::instrument(skip_all, level = "debug")] +pub async fn policyserv_check(&self, event_id: &EventId, room_id: &RoomId) -> Result { + let Ok(policyserver) = self + .services + .state_accessor + .room_state_get_content(room_id, &StateEventType::RoomPolicy, "") + .await + .map(|c: RoomPolicyEventContent| c) + else { + return Ok(()); + }; + + let via = match policyserver.via { + | Some(ref via) => ServerName::parse(via)?, + | None => { + debug!("No policy server configured for room {room_id}"); + return Ok(()); + }, + }; + let response = self + .services + .sending + .send_federation_request(via, PolicyRequest { event_id: event_id.to_owned() }) + .await; + let response = match response { + | Ok(response) => response, + | Err(e) => { + warn!("Failed to contact policy server {via} for room {room_id}: {e}"); + return Ok(()); + }, + }; + if response.recommendation == "spam" { + warn!("Event {event_id} in room {room_id} was marked as spam by policy server {via}"); + return Err!(Request(Forbidden("Event was marked as spam by policy server"))); + }; + + Ok(()) +} diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 45675da8..3213db29 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -1,4 +1,5 @@ mod acl_check; +mod call_policyserv; mod fetch_and_handle_outliers; mod fetch_prev; mod fetch_state; diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 97d3df97..43ca83c4 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -1,12 +1,6 @@ use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant}; -use conduwuit::{ - Err, Result, debug, debug_info, err, implement, - matrix::{EventTypeExt, PduEvent, StateKey, state_res}, - trace, - utils::stream::{BroadbandExt, ReadyExt}, - warn, -}; +use conduwuit::{Err, Result, debug, debug_info, err, implement, info, matrix::{EventTypeExt, PduEvent, StateKey, state_res}, trace, utils::stream::{BroadbandExt, ReadyExt}, warn, Event}; use futures::{FutureExt, StreamExt, future::ready}; use ruma::{CanonicalJsonValue, RoomId, ServerName, events::StateEventType}; @@ -242,6 +236,20 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( return Err!(Request(InvalidParam("Event has been soft failed"))); } + // 15. If the event is not a state event, ask the policy server about it + if incoming_pdu.state_key.is_none() { + debug!("Checking policy server for event {}", incoming_pdu.event_id); + let policy = self.policyserv_check( + &incoming_pdu.event_id, + room_id, + ); + if let Err(e) = policy.await { + warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id); + return Err!(Request(Forbidden("Event was marked as spam by policy server"))); + } + debug!("Policy server check passed for event {}", incoming_pdu.event_id); + } + // Now that the event has passed all auth it is added into the timeline. // We use the `state_at_event` instead of `state_after` so we accurately // represent the state for this event. From cd479604fe2bb03816c89d2ceed4d932def27984 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Thu, 19 Jun 2025 20:28:13 +0100 Subject: [PATCH 2/7] Don't call policy server on ourselves (cherry picked from commit a8c10f6317011ee9db3db968f7a4f81284211780) --- src/service/rooms/event_handler/upgrade_outlier_pdu.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 43ca83c4..c29425c6 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -237,7 +237,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( } // 15. If the event is not a state event, ask the policy server about it - if incoming_pdu.state_key.is_none() { + if incoming_pdu.state_key.is_none() && incoming_pdu.sender().server_name() != self.services.globals.server_name() { debug!("Checking policy server for event {}", incoming_pdu.event_id); let policy = self.policyserv_check( &incoming_pdu.event_id, From ea2d508e47eb734634437ed8321c06d47e3e0ee3 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Thu, 19 Jun 2025 20:35:56 +0100 Subject: [PATCH 3/7] Correctly mark things as soft failed when checking the policyserv (cherry picked from commit 3b876ea029b7ec44db143ead31e1696eb4c44b5e) --- .../event_handler/upgrade_outlier_pdu.rs | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index c29425c6..7b42b093 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -1,6 +1,12 @@ use std::{borrow::Borrow, collections::BTreeMap, iter::once, sync::Arc, time::Instant}; -use conduwuit::{Err, Result, debug, debug_info, err, implement, info, matrix::{EventTypeExt, PduEvent, StateKey, state_res}, trace, utils::stream::{BroadbandExt, ReadyExt}, warn, Event}; +use conduwuit::{ + Err, Event, Result, debug, debug_info, err, implement, info, + matrix::{EventTypeExt, PduEvent, StateKey, state_res}, + trace, + utils::stream::{BroadbandExt, ReadyExt}, + warn, +}; use futures::{FutureExt, StreamExt, future::ready}; use ruma::{CanonicalJsonValue, RoomId, ServerName, events::StateEventType}; @@ -115,8 +121,8 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( .map_err(|e| err!(Request(Forbidden("Auth check failed: {e:?}"))))?; // Soft fail check before doing state res - debug!("Performing soft-fail check"); - let soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_id)) { + debug!("Performing soft-fail check on {}", incoming_pdu.event_id); + let mut soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_id)) { | (false, _) => true, | (true, None) => false, | (true, Some(redact_id)) => @@ -209,6 +215,21 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( .await?; } + // 14-pre. If the event is not a state event, ask the policy server about it + if incoming_pdu.state_key.is_none() + && incoming_pdu.sender().server_name() != self.services.globals.server_name() + { + debug!("Checking policy server for event {}", incoming_pdu.event_id); + let policy = self.policyserv_check(&incoming_pdu.event_id, room_id); + if let Err(e) = policy.await { + warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id); + if !soft_fail { + soft_fail = true; + } + } + debug!("Policy server check passed for event {}", incoming_pdu.event_id); + } + // 14. Check if the event passes auth based on the "current state" of the room, // if not soft fail it if soft_fail { @@ -236,20 +257,6 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( return Err!(Request(InvalidParam("Event has been soft failed"))); } - // 15. If the event is not a state event, ask the policy server about it - if incoming_pdu.state_key.is_none() && incoming_pdu.sender().server_name() != self.services.globals.server_name() { - debug!("Checking policy server for event {}", incoming_pdu.event_id); - let policy = self.policyserv_check( - &incoming_pdu.event_id, - room_id, - ); - if let Err(e) = policy.await { - warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id); - return Err!(Request(Forbidden("Event was marked as spam by policy server"))); - } - debug!("Policy server check passed for event {}", incoming_pdu.event_id); - } - // Now that the event has passed all auth it is added into the timeline. // We use the `state_at_event` instead of `state_after` so we accurately // represent the state for this event. From 33fbc43f764aa2aca98e5538edb61d0b34372f51 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Thu, 19 Jun 2025 22:13:40 +0100 Subject: [PATCH 4/7] Almost call with the PDU Need to figure out why signing is sad (cherry picked from commit 6134b971633c9981871c1c9d060a677588714141) --- Cargo.lock | 22 ++++----- Cargo.toml | 2 +- .../rooms/event_handler/call_policyserv.rs | 47 +++++++++++++------ .../event_handler/upgrade_outlier_pdu.rs | 2 +- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44c210f1..49c45327 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3695,7 +3695,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "assign", "js_int", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.10.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "js_int", "ruma-common", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "as_variant", "assign", @@ -3750,7 +3750,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "as_variant", "base64 0.22.1", @@ -3782,7 +3782,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "as_variant", "indexmap 2.9.0", @@ -3807,7 +3807,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "bytes", "headers", @@ -3829,7 +3829,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "js_int", "thiserror 2.0.12", @@ -3838,7 +3838,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "js_int", "ruma-common", @@ -3848,7 +3848,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3863,7 +3863,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "js_int", "ruma-common", @@ -3875,7 +3875,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.15.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=781606d1fafbf2daa220fd354d9ad0479a308cd1#781606d1fafbf2daa220fd354d9ad0479a308cd1" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" dependencies = [ "base64 0.22.1", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 2ad5c1ca..40a8ea0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -350,7 +350,7 @@ version = "0.1.2" [workspace.dependencies.ruma] git = "https://forgejo.ellis.link/continuwuation/ruwuma" #branch = "conduwuit-changes" -rev = "781606d1fafbf2daa220fd354d9ad0479a308cd1" +rev = "1faaf474b122159a04518214e8248b465dae06c9" features = [ "compat", "rand", diff --git a/src/service/rooms/event_handler/call_policyserv.rs b/src/service/rooms/event_handler/call_policyserv.rs index 548a0081..f40ec3c7 100644 --- a/src/service/rooms/event_handler/call_policyserv.rs +++ b/src/service/rooms/event_handler/call_policyserv.rs @@ -1,21 +1,18 @@ -use conduwuit::{Err, Result, debug, implement, trace, warn}; -use ruma::{ - EventId, OwnedEventId, OwnedServerName, RoomId, ServerName, - api::federation::room::policy::v1::{Request as PolicyRequest, Response as PolicyResponse}, - events::{ - StateEventType, - room::{ - policy::{PolicyServerResponseContent, RoomPolicyEventContent}, - server_acl::RoomServerAclEventContent, - }, - }, +use conduwuit::{ + Err, Event, PduEvent, Result, debug, implement, utils::to_canonical_object, warn, }; -use serde::{Deserialize, Serialize}; +use ruma::{ + RoomId, ServerName, + api::federation::room::policy::v1::Request as PolicyRequest, + events::StateEventType, + events::room::policy::RoomPolicyEventContent, +}; +use ruma::canonical_json::to_canonical_value; /// Returns Ok if the policy server allows the event #[implement(super::Service)] #[tracing::instrument(skip_all, level = "debug")] -pub async fn policyserv_check(&self, event_id: &EventId, room_id: &RoomId) -> Result { +pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result { let Ok(policyserver) = self .services .state_accessor @@ -33,10 +30,27 @@ pub async fn policyserv_check(&self, event_id: &EventId, room_id: &RoomId) -> Re return Ok(()); }, }; + // TODO: dont do *this* + let pdu_json = self.services.timeline.get_pdu_json(pdu.event_id()).await?; + let outgoing = self.services + .sending + .convert_to_outgoing_federation_event(pdu_json) + .await; + // let s = match serde_json::to_string(outgoing.as_ref()) { + // | Ok(s) => s, + // | Err(e) => { + // warn!("Failed to convert pdu {} to outgoing federation event: {e}", pdu.event_id()); + // return Err!(Request(InvalidParam("Failed to convert PDU to outgoing event."))); + // }, + // }; let response = self .services .sending - .send_federation_request(via, PolicyRequest { event_id: event_id.to_owned() }) + .send_federation_request(via, PolicyRequest { + event_id: pdu.event_id().to_owned(), + // pdu: Some(outgoing), + pdu: None, // TODO: figure out why providing the PDU makes the signature invalid + }) .await; let response = match response { | Ok(response) => response, @@ -46,7 +60,10 @@ pub async fn policyserv_check(&self, event_id: &EventId, room_id: &RoomId) -> Re }, }; if response.recommendation == "spam" { - warn!("Event {event_id} in room {room_id} was marked as spam by policy server {via}"); + warn!( + "Event {} in room {room_id} was marked as spam by policy server {via}", + pdu.event_id().to_owned() + ); return Err!(Request(Forbidden("Event was marked as spam by policy server"))); }; diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 7b42b093..2c841b29 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -220,7 +220,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( && incoming_pdu.sender().server_name() != self.services.globals.server_name() { debug!("Checking policy server for event {}", incoming_pdu.event_id); - let policy = self.policyserv_check(&incoming_pdu.event_id, room_id); + let policy = self.policyserv_check(&incoming_pdu, room_id); if let Err(e) = policy.await { warn!("Policy server check failed for event {}: {e}", incoming_pdu.event_id); if !soft_fail { From 333ad204ea2fee829fa093922b93e998ef268789 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Fri, 20 Jun 2025 01:27:21 +0100 Subject: [PATCH 5/7] Policy checks and alsl remove assertatte ion (cherry picked from commit f0ff0e4599c3db8786693e43691b164bb0b7e3c3) --- Cargo.lock | 22 +++++++++---------- Cargo.toml | 2 +- .../rooms/event_handler/call_policyserv.rs | 4 ++-- src/service/rooms/timeline/mod.rs | 21 +++++++++++++++++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49c45327..e81603fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3695,7 +3695,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "assign", "js_int", @@ -3715,7 +3715,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.10.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "js_int", "ruma-common", @@ -3727,7 +3727,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "as_variant", "assign", @@ -3750,7 +3750,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "as_variant", "base64 0.22.1", @@ -3782,7 +3782,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "as_variant", "indexmap 2.9.0", @@ -3807,7 +3807,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "bytes", "headers", @@ -3829,7 +3829,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "js_int", "thiserror 2.0.12", @@ -3838,7 +3838,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "js_int", "ruma-common", @@ -3848,7 +3848,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3863,7 +3863,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "js_int", "ruma-common", @@ -3875,7 +3875,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.15.0" -source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1faaf474b122159a04518214e8248b465dae06c9#1faaf474b122159a04518214e8248b465dae06c9" +source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6#8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" dependencies = [ "base64 0.22.1", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 40a8ea0a..4456f0ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -350,7 +350,7 @@ version = "0.1.2" [workspace.dependencies.ruma] git = "https://forgejo.ellis.link/continuwuation/ruwuma" #branch = "conduwuit-changes" -rev = "1faaf474b122159a04518214e8248b465dae06c9" +rev = "8ea4885e34a61fa4b7c0bb38b39ec66a772d89a6" features = [ "compat", "rand", diff --git a/src/service/rooms/event_handler/call_policyserv.rs b/src/service/rooms/event_handler/call_policyserv.rs index f40ec3c7..04971312 100644 --- a/src/service/rooms/event_handler/call_policyserv.rs +++ b/src/service/rooms/event_handler/call_policyserv.rs @@ -43,13 +43,13 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result // return Err!(Request(InvalidParam("Failed to convert PDU to outgoing event."))); // }, // }; + debug!("Checking pdu {outgoing:?} for spam with policy server {via} for room {room_id}"); let response = self .services .sending .send_federation_request(via, PolicyRequest { event_id: pdu.event_id().to_owned(), - // pdu: Some(outgoing), - pdu: None, // TODO: figure out why providing the PDU makes the signature invalid + pdu: Some(outgoing), }) .await; let response = match response { diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 4b2f3cb2..2dab154a 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -698,6 +698,20 @@ impl Service { .await .saturating_add(uint!(1)); + if state_key.is_none() { + if prev_events.is_empty() { + warn!("Timeline event had zero prev_events, something broke."); + return Err!(Request(Unknown("Timeline event had zero prev_events."))); + } + if depth.le(&uint!(2)) { + warn!( + "Had unsafe depth of {depth} in {room_id} when creating non-state event. \ + Bad!" + ); + return Err!(Request(Unknown("Unsafe depth for non-state event."))); + } + }; + let mut unsigned = unsigned.unwrap_or_default(); if let Some(state_key) = &state_key { @@ -757,6 +771,10 @@ impl Service { ready(auth_events.get(&key)) }; + debug!( + "running auth check on new {} event by {} in {}", + pdu.kind, pdu.sender, pdu.room_id + ); let auth_check = state_res::auth_check( &room_version, &pdu, @@ -961,8 +979,9 @@ impl Service { state_lock: &'a RoomMutexGuard, ) -> Result> where - Leaves: Iterator + Send + 'a, + Leaves: Iterator + Send + Clone + 'a, { + // assert!(new_room_leaves.clone().count() > 0, "extremities are empty"); // We append to state before appending the pdu, so we don't have a moment in // time with the pdu without it's state. This is okay because append_pdu can't // fail. From 124de732e4bfdebf3b1bf9e19a44e7f3ed4491d6 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Fri, 20 Jun 2025 01:33:57 +0100 Subject: [PATCH 6/7] no! (cherry picked from commit a3d8e222a2d3a45ccef6142a55f7ff8a8a265ad4) --- .../rooms/event_handler/upgrade_outlier_pdu.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 2c841b29..2cce47a9 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -44,7 +44,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( return Err!(Request(InvalidParam("Event has been soft failed"))); } - debug!("Upgrading to timeline pdu"); + debug!("Upgrading pdu {} from outlier to timeline pdu", incoming_pdu.event_id); let timer = Instant::now(); let room_version_id = get_room_version_id(create_event)?; @@ -52,7 +52,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( // backwards extremities doing all the checks in this list starting at 1. // These are not timeline events. - debug!("Resolving state at event"); + debug!("Resolving state at event {}", incoming_pdu.event_id); let mut state_at_incoming_event = if incoming_pdu.prev_events.len() == 1 { self.state_at_incoming_degree_one(&incoming_pdu).await? } else { @@ -70,7 +70,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( state_at_incoming_event.expect("we always set this to some above"); let room_version = to_room_version(&room_version_id); - debug!("Performing auth check"); + debug!("Performing auth check to upgrade {}", incoming_pdu.event_id); // 11. Check the auth of the event passes based on the state of the event let state_fetch_state = &state_at_incoming_event; let state_fetch = |k: StateEventType, s: StateKey| async move { @@ -80,6 +80,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( self.services.timeline.get_pdu(event_id).await.ok() }; + debug!("running auth check on {}", incoming_pdu.event_id); let auth_check = state_res::event_auth::auth_check( &room_version, &incoming_pdu, @@ -93,7 +94,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( return Err!(Request(Forbidden("Event has failed auth check with state at the event."))); } - debug!("Gathering auth events"); + debug!("Gathering auth events for {}", incoming_pdu.event_id); let auth_events = self .services .state @@ -111,6 +112,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( ready(auth_events.get(&key).cloned()) }; + debug!("running auth check on {} with claimed state auth", incoming_pdu.event_id); let auth_check = state_res::event_auth::auth_check( &room_version, &incoming_pdu, @@ -233,7 +235,8 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( // 14. Check if the event passes auth based on the "current state" of the room, // if not soft fail it if soft_fail { - debug!("Soft failing event"); + info!("Soft failing event {}", incoming_pdu.event_id); + // assert!(extremities.is_empty(), "soft_fail extremities empty"); let extremities = extremities.iter().map(Borrow::borrow); self.services From 67cfd5fd996d31188a4e859cff41ce588afc8d2f Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Fri, 20 Jun 2025 02:01:26 +0100 Subject: [PATCH 7/7] Run cargo fmt --- src/service/rooms/event_handler/call_policyserv.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/service/rooms/event_handler/call_policyserv.rs b/src/service/rooms/event_handler/call_policyserv.rs index 04971312..4a52227d 100644 --- a/src/service/rooms/event_handler/call_policyserv.rs +++ b/src/service/rooms/event_handler/call_policyserv.rs @@ -4,10 +4,9 @@ use conduwuit::{ use ruma::{ RoomId, ServerName, api::federation::room::policy::v1::Request as PolicyRequest, - events::StateEventType, - events::room::policy::RoomPolicyEventContent, + canonical_json::to_canonical_value, + events::{StateEventType, room::policy::RoomPolicyEventContent}, }; -use ruma::canonical_json::to_canonical_value; /// Returns Ok if the policy server allows the event #[implement(super::Service)] @@ -32,16 +31,17 @@ pub async fn policyserv_check(&self, pdu: &PduEvent, room_id: &RoomId) -> Result }; // TODO: dont do *this* let pdu_json = self.services.timeline.get_pdu_json(pdu.event_id()).await?; - let outgoing = self.services + let outgoing = self + .services .sending .convert_to_outgoing_federation_event(pdu_json) .await; // let s = match serde_json::to_string(outgoing.as_ref()) { // | Ok(s) => s, // | Err(e) => { - // warn!("Failed to convert pdu {} to outgoing federation event: {e}", pdu.event_id()); - // return Err!(Request(InvalidParam("Failed to convert PDU to outgoing event."))); - // }, + // warn!("Failed to convert pdu {} to outgoing federation event: {e}", + // pdu.event_id()); return Err!(Request(InvalidParam("Failed to convert PDU + // to outgoing event."))); }, // }; debug!("Checking pdu {outgoing:?} for spam with policy server {via} for room {room_id}"); let response = self