diff --git a/src/service/rooms/event_handler/fetch_auth.rs b/src/service/rooms/event_handler/fetch_auth.rs index 8a905378f..b36fef05d 100644 --- a/src/service/rooms/event_handler/fetch_auth.rs +++ b/src/service/rooms/event_handler/fetch_auth.rs @@ -1,6 +1,6 @@ use std::collections::{HashMap, hash_map}; -use conduwuit::{Err, Event, EventTypeExt, PduEvent, Result, err}; +use conduwuit::{Err, Event, EventTypeExt, PduEvent, Result, err, warn}; use ruma::{ CanonicalJsonObject, OwnedEventId, ServerName, api::federation::authorization::get_event_authorization, @@ -50,16 +50,45 @@ pub(super) async fn fetch_and_persist_event_auth( for auth_pdu_json in event_auth.auth_chain { let (auth_event_room_id, auth_event_id, auth_pdu_json) = - self.parse_incoming_pdu(&auth_pdu_json).await?; + match self.parse_incoming_pdu(&auth_pdu_json).await { + | Ok(parsed) => parsed, + | Err(e) => { + warn!(error=?e, "Dropping auth chain event as it could not be parsed"); + continue; + }, + }; + if !Self::pdu_format_check_1(&auth_pdu_json) { + // drop this PDU + warn!(%auth_event_id, "Dropping auth chain event as it is too large"); + continue; + } + let auth_pdu_json = match self + .signature_hash_check_2_3(auth_pdu_json, room_version_rules) + .await + { + | Ok(pdu_json) => pdu_json, + | Err(e) => { + // drop this PDU + warn!( + %auth_event_id, + error=?e, + "Dropping auth chain event as it has an invalid signature" + ); + continue; + }, + }; + + // PDU check 4 is done when we've finished aggregating if auth_event_room_id != incoming_event.room_id_or_hash() { return Err!(Request(Forbidden( - "Auth event {auth_event_id} is in {auth_event_room_id}, not {}.", + "Auth chain event {auth_event_id} is in {auth_event_room_id}, not {}.", incoming_event.room_id_or_hash() ))); } let auth_pdu = PduEvent::from_id_val(&auth_event_id, auth_pdu_json).map_err(|e| { err!(Request(BadJson("Invalid PDU {auth_event_id} in auth chain: {e}"))) })?; + if auth_pdu.state_key().is_none() { return Err!(Request(BadJson( "Invalid PDU {auth_event_id} in auth_chain: not a state event" @@ -129,8 +158,9 @@ async fn authorise_remote_auth_chain( // IMPORTANT: We can't use the handy dandy `handle_outlier_pdu` function here // because it may then try to fetch missing auth events, resulting in deep - // recursion. We will do the minimum required steps to validate the PDU here - // (steps 1 through 4). + // recursion. We will do the minimum required steps to validate the PDU here. + // Checks 1-3 were already done before this function is called, so we only need + // to do check 4. let mut auth_events_by_key: HashMap<_, _> = HashMap::with_capacity(pdu.auth_events.len()); diff --git a/src/service/rooms/event_handler/handle_outlier_pdu.rs b/src/service/rooms/event_handler/handle_outlier_pdu.rs index 0104d4b6b..fe19f503f 100644 --- a/src/service/rooms/event_handler/handle_outlier_pdu.rs +++ b/src/service/rooms/event_handler/handle_outlier_pdu.rs @@ -1,16 +1,11 @@ use std::collections::{BTreeMap, HashMap, hash_map}; use conduwuit::{ - Err, Event, EventTypeExt, PduEvent, Result, debug, debug_info, debug_warn, err, info, trace, - warn, -}; -use ruma::{ - CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, RoomId, ServerName, - canonical_json::redact, + Err, Event, EventTypeExt, PduEvent, Result, debug, debug_warn, err, info, trace, warn, }; +use ruma::{CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, RoomId, ServerName}; use super::{check_room_id, get_room_version_rules}; -use crate::rooms::timeline::pdu_fits; impl super::Service { /// Handles a PDU as an outlier, performing basic checks like signatures and diff --git a/src/service/rooms/event_handler/pdu_checks.rs b/src/service/rooms/event_handler/pdu_checks.rs index da96c1295..60991b799 100644 --- a/src/service/rooms/event_handler/pdu_checks.rs +++ b/src/service/rooms/event_handler/pdu_checks.rs @@ -2,7 +2,7 @@ use conduwuit::{ Err, Event, EventTypeExt, PduEvent, Result, debug, debug::DebugInspect, debug_error, - debug_info, err, info, matrix::StateKey, state_res, trace, warn, + debug_info, err, info, matrix::StateKey, state_res, trace, }; use futures::future::ready; use ruma::{ @@ -34,7 +34,7 @@ pub(super) async fn signature_hash_check_2_3( match self .services .server_keys - .verify_event(&pdu_json, &room_version_rules) + .verify_event(&pdu_json, room_version_rules) .await { | Ok(ruma::signatures::Verified::All) => Ok(pdu_json),