diff --git a/src/api/server/invite.rs b/src/api/server/invite.rs index b81aa4f96..8d1ebbc5f 100644 --- a/src/api/server/invite.rs +++ b/src/api/server/invite.rs @@ -6,6 +6,7 @@ use base64::{Engine as _, engine::general_purpose}; use conduwuit::{ Err, Error, EventTypeExt, PduEvent, Result, err, error, matrix::{Event, StateKey, event::gen_event_id}, + state_res, utils::hash::sha256, warn, }; @@ -70,7 +71,7 @@ pub(crate) async fn create_invite_route( // First, validate the invite room state, so we can compare with the create // event. - let (create_event_id, _) = validate_invite_state( + let (create_event_id, state) = validate_invite_state( &services, &body.invite_room_state, &room_version_rules, @@ -84,7 +85,7 @@ pub(crate) async fn create_invite_route( &body.event, &room_version_rules, &body.identity, - create_event_id, + create_event_id.clone(), body.room_id.clone(), body.event_id.clone(), ) @@ -152,6 +153,20 @@ pub(crate) async fn create_invite_route( .server_in_room(services.globals.server_name(), &body.room_id) .await { + // We will start by recording the room's create event as an outlier. + // This will allow us to recognise it later in case the sender revokes the + // invite over federation later. We could store more state from the invite + // request, but we will get that during send_join anyway. + let create_event_json = state + .get(&StateEventType::RoomCreate.with_state_key("")) + .expect("must have create event in invite state by this point"); + // This is safe to just add directly as an outlier as we already auth checked it + // during validation. + services + .rooms + .outlier + .add_pdu_outlier(&create_event_id, create_event_json); + services .rooms .state_cache @@ -387,6 +402,28 @@ async fn validate_invite_state( ))), | Entry::Vacant(entry) => { if entry.key().0 == StateEventType::RoomCreate { + // Ensure this is a legal create event. + let pdu_event = + PduEvent::from_id_val(&state_event_id, state_event_json.clone()) + .expect("must be able to create pdu event from event json"); + if !state_res::auth_check( + room_version_rules, + &pdu_event, + None, + |_, _| async { + unreachable!( + "No state should be fetched when processing a lone create event" + ); + }, + &pdu_event, + ) + .await + .unwrap_or_default() + { + return Err!(Request(InvalidParam( + "m.room.create event fails auth check" + ))); + } create_event_id = Some(state_event_id); } entry.insert(state_event_json); diff --git a/src/service/rooms/event_handler/handle_outlier_pdu.rs b/src/service/rooms/event_handler/handle_outlier_pdu.rs index 72285406d..843dea038 100644 --- a/src/service/rooms/event_handler/handle_outlier_pdu.rs +++ b/src/service/rooms/event_handler/handle_outlier_pdu.rs @@ -14,10 +14,12 @@ impl super::Service { /// This performs steps 1 through 4 of [S-S section 5.1][spec], returning /// the parsed PDU and modified JSON object. /// + /// **External callers likely want `handle_incoming_pdu` instead.** + /// /// [spec]: https://spec.matrix.org/v1.19/server-server-api/#checks-performed-on-receipt-of-a-pdu #[allow(clippy::too_many_arguments)] #[tracing::instrument(name = "handle_outlier", skip_all)] - pub(super) async fn handle_outlier_pdu<'a, Pdu>( + pub async fn handle_outlier_pdu<'a, Pdu>( &self, origin: &'a ServerName, create_event: &'a Pdu, @@ -54,7 +56,6 @@ impl super::Service { })?; value.remove("unsigned"); - let room_version_rules = get_room_version_rules(create_event)?; // 2. Check signatures, otherwise drop. // 3. Check content hash, redacting the event if it fails. diff --git a/src/service/rooms/event_handler/pdu_checks.rs b/src/service/rooms/event_handler/pdu_checks.rs index d258f834d..1f84e2b41 100644 --- a/src/service/rooms/event_handler/pdu_checks.rs +++ b/src/service/rooms/event_handler/pdu_checks.rs @@ -94,7 +94,7 @@ impl super::Service { /// If the auth check fails, false is returned, otherwise true. /// /// [spec]: https://spec.matrix.org/v1.19/server-server-api/#checks-performed-on-receipt-of-a-pdu - pub(super) async fn auth_state_check_4( + pub async fn auth_state_check_4( &self, pdu: &PduEvent, room_version_rules: &RoomVersionRules,