mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 13:16:56 +00:00
refactor: Move PDU checks 1, 2, and 3 into pdu_checks.rs
This commit is contained in:
4 files changed
+53
-24
No files matched your search
@@ -127,6 +127,11 @@ impl super::Service {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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).
|
||||||
|
|
||||||
let mut auth_events_by_key: HashMap<_, _> =
|
let mut auth_events_by_key: HashMap<_, _> =
|
||||||
HashMap::with_capacity(pdu.auth_events.len());
|
HashMap::with_capacity(pdu.auth_events.len());
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::rooms::event_handler::{build_local_dag, fetch_and_handle_outliers::Da
|
|||||||
|
|
||||||
impl super::Service {
|
impl super::Service {
|
||||||
/// Fetches any missing prev_events for this event and persists them before
|
/// Fetches any missing prev_events for this event and persists them before
|
||||||
/// returning.
|
/// returning. The caller is responsible for then handling the incoming PDU.
|
||||||
pub(super) async fn fetch_prevs(
|
pub(super) async fn fetch_prevs(
|
||||||
&self,
|
&self,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl super::Service {
|
|||||||
|
|
||||||
// 1. Check that the PDU follows the format for the room version
|
// 1. Check that the PDU follows the format for the room version
|
||||||
// (in this case, just size check)
|
// (in this case, just size check)
|
||||||
if !pdu_fits(&value) {
|
if !Self::pdu_format_check_1(&value) {
|
||||||
warn!(
|
warn!(
|
||||||
"dropping incoming PDU {event_id} in room {room_id} from {origin} because it \
|
"dropping incoming PDU {event_id} in room {room_id} from {origin} because it \
|
||||||
exceeds 65535 bytes or is otherwise too large."
|
exceeds 65535 bytes or is otherwise too large."
|
||||||
@@ -63,24 +63,9 @@ impl super::Service {
|
|||||||
|
|
||||||
// 2. Check signatures, otherwise drop.
|
// 2. Check signatures, otherwise drop.
|
||||||
// 3. Check content hash, redacting the event if it fails.
|
// 3. Check content hash, redacting the event if it fails.
|
||||||
let mut incoming_pdu = match self
|
let mut incoming_pdu = self
|
||||||
.services
|
.signature_hash_check_2_3(value, &room_version_rules)
|
||||||
.server_keys
|
.await?;
|
||||||
.verify_event(&value, &room_version_rules)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
| Ok(ruma::signatures::Verified::All) => value,
|
|
||||||
| Ok(ruma::signatures::Verified::Signatures) => {
|
|
||||||
debug_info!("Content hash mismatch, redacting event and continuing");
|
|
||||||
redact(value, &room_version_rules.redaction, None)
|
|
||||||
.map_err(|e| err!(Request(BadJson("Unable to redact {event_id}: {e}"))))?
|
|
||||||
},
|
|
||||||
| Err(e) => {
|
|
||||||
return Err!(Request(Forbidden(debug_error!(
|
|
||||||
"Signature verification failed for {event_id}: {e}"
|
|
||||||
))));
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Now that we have checked the signature and hashes we can add the eventID and
|
// Now that we have checked the signature and hashes we can add the eventID and
|
||||||
// convert to our PduEvent type
|
// convert to our PduEvent type
|
||||||
|
|||||||
@@ -1,16 +1,55 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use conduwuit::{
|
use conduwuit::{
|
||||||
Err, Event, EventTypeExt, PduEvent, Result, debug, debug::DebugInspect, debug_error, err,
|
Err, Event, EventTypeExt, PduEvent, Result, debug, debug::DebugInspect, debug_error,
|
||||||
info, matrix::StateKey, state_res, trace,
|
debug_info, err, info, matrix::StateKey, state_res, trace, warn,
|
||||||
};
|
};
|
||||||
use futures::future::ready;
|
use futures::future::ready;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
CanonicalJsonObject, OwnedEventId, ServerName, api::error::ErrorKind, events::StateEventType,
|
CanonicalJsonObject, OwnedEventId, ServerName, api::error::ErrorKind, canonical_json::redact,
|
||||||
room_version_rules::RoomVersionRules,
|
events::StateEventType, room_version_rules::RoomVersionRules,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::rooms::timeline::pdu_fits;
|
||||||
|
|
||||||
impl super::Service {
|
impl super::Service {
|
||||||
|
/// Checks that the PDU conforms to the PDU format (check 1). This is
|
||||||
|
/// already mostly done during deserialisation, so this function just checks
|
||||||
|
/// that the PDU isn't a too large.
|
||||||
|
pub(super) fn pdu_format_check_1(pdu_json: &CanonicalJsonObject) -> bool {
|
||||||
|
// NOTE: if we do any more validation outside of deserialisation, it has to be
|
||||||
|
// done here.
|
||||||
|
pdu_fits(pdu_json)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks that the PDU has a valid signature (check 2), and redacts it if
|
||||||
|
/// the content hash verification fails (check 3), returning the
|
||||||
|
/// potentially modified JSON. Returns an error if the PDU cannot be
|
||||||
|
/// redacted, or fails signature verification.
|
||||||
|
pub(super) async fn signature_hash_check_2_3(
|
||||||
|
&self,
|
||||||
|
pdu_json: CanonicalJsonObject,
|
||||||
|
room_version_rules: &RoomVersionRules,
|
||||||
|
) -> Result<CanonicalJsonObject> {
|
||||||
|
match self
|
||||||
|
.services
|
||||||
|
.server_keys
|
||||||
|
.verify_event(&pdu_json, &room_version_rules)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
| Ok(ruma::signatures::Verified::All) => Ok(pdu_json),
|
||||||
|
| Ok(ruma::signatures::Verified::Signatures) => {
|
||||||
|
debug_info!("Content hash mismatch, redacting event and continuing");
|
||||||
|
let redacted = redact(pdu_json, &room_version_rules.redaction, None)
|
||||||
|
.map_err(|e| err!(Request(BadJson("Unable to redact event: {e}"))))?;
|
||||||
|
Ok(redacted)
|
||||||
|
},
|
||||||
|
| Err(e) => {
|
||||||
|
Err!(Request(Forbidden(debug_error!("Signature verification failed: {e}"))))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Checks PDU check 4: Passes authorisation rules based on the event's auth
|
/// Checks PDU check 4: Passes authorisation rules based on the event's auth
|
||||||
/// events ([spec]).
|
/// events ([spec]).
|
||||||
///
|
///
|
||||||
|
|||||||
Reference in new issue
Block a user