feat: join cursed rooms
this removes several restrictions and tries to continue verifying a pdu event if some auth events fail (it drops/ignores bad pdus)next
parent
8b40e0a85f
commit
5951294638
|
@ -2120,7 +2120,7 @@ checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "state-res"
|
name = "state-res"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/timokoesters/state-res?rev=84e70c062708213d01281438598e16f13dffeda4#84e70c062708213d01281438598e16f13dffeda4"
|
source = "git+https://github.com/timokoesters/state-res?rev=9bb46ae681bfc361cff740e78dc42bb711db9779#9bb46ae681bfc361cff740e78dc42bb711db9779"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.10.0",
|
"itertools 0.10.0",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -23,7 +23,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "c1693569f15920e408aa6a26b7
|
||||||
#ruma = { path = "../ruma/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
#ruma = { path = "../ruma/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "unstable-pre-spec", "unstable-exhaustive-types"] }
|
||||||
|
|
||||||
# Used when doing state resolution
|
# Used when doing state resolution
|
||||||
state-res = { git = "https://github.com/timokoesters/state-res", rev = "84e70c062708213d01281438598e16f13dffeda4", features = ["unstable-pre-spec"] }
|
state-res = { git = "https://github.com/timokoesters/state-res", rev = "9bb46ae681bfc361cff740e78dc42bb711db9779", features = ["unstable-pre-spec"] }
|
||||||
#state-res = { path = "../state-res", features = ["unstable-pre-spec"] }
|
#state-res = { path = "../state-res", features = ["unstable-pre-spec"] }
|
||||||
|
|
||||||
# Used for long polling and federation sender, should be the same as rocket::tokio
|
# Used for long polling and federation sender, should be the same as rocket::tokio
|
||||||
|
|
|
@ -527,7 +527,7 @@ async fn join_room_by_id_helper(
|
||||||
.map_err(|_| Error::BadServerResponse("Invalid PDU in send_join response."))?;
|
.map_err(|_| Error::BadServerResponse("Invalid PDU in send_join response."))?;
|
||||||
|
|
||||||
let mut state = BTreeMap::new();
|
let mut state = BTreeMap::new();
|
||||||
let mut pub_key_map = RwLock::new(BTreeMap::new());
|
let pub_key_map = RwLock::new(BTreeMap::new());
|
||||||
|
|
||||||
for result in futures::future::join_all(
|
for result in futures::future::join_all(
|
||||||
send_join_response
|
send_join_response
|
||||||
|
@ -538,7 +538,11 @@ async fn join_room_by_id_helper(
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
let (event_id, value) = result?;
|
let (event_id, value) = match result {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
|
||||||
let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| {
|
let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| {
|
||||||
warn!("{:?}: {}", value, e);
|
warn!("{:?}: {}", value, e);
|
||||||
Error::BadServerResponse("Invalid PDU in send_join response.")
|
Error::BadServerResponse("Invalid PDU in send_join response.")
|
||||||
|
@ -593,9 +597,20 @@ async fn join_room_by_id_helper(
|
||||||
|
|
||||||
db.rooms.force_state(room_id, state, &db.globals)?;
|
db.rooms.force_state(room_id, state, &db.globals)?;
|
||||||
|
|
||||||
for pdu in send_join_response.room_state.auth_chain.iter() {
|
for result in futures::future::join_all(
|
||||||
let (event_id, value) =
|
send_join_response
|
||||||
validate_and_add_event_id(pdu, &room_version, &mut pub_key_map, &db).await?;
|
.room_state
|
||||||
|
.auth_chain
|
||||||
|
.iter()
|
||||||
|
.map(|pdu| validate_and_add_event_id(pdu, &room_version, &pub_key_map, &db)),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
let (event_id, value) = match result {
|
||||||
|
Ok(t) => t,
|
||||||
|
Err(_) => continue,
|
||||||
|
};
|
||||||
|
|
||||||
let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| {
|
let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| {
|
||||||
warn!("{:?}: {}", value, e);
|
warn!("{:?}: {}", value, e);
|
||||||
Error::BadServerResponse("Invalid PDU in send_join response.")
|
Error::BadServerResponse("Invalid PDU in send_join response.")
|
||||||
|
|
25
src/pdu.rs
25
src/pdu.rs
|
@ -166,22 +166,17 @@ impl PduEvent {
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> {
|
pub fn to_sync_state_event(&self) -> Raw<AnySyncStateEvent> {
|
||||||
let json = format!(
|
let json = json!({
|
||||||
r#"{{"content":{},"type":"{}","event_id":"{}","sender":"{}","origin_server_ts":{},"unsigned":{},"state_key":"{}"}}"#,
|
"content": self.content,
|
||||||
self.content,
|
"type": self.kind,
|
||||||
self.kind,
|
"event_id": self.event_id,
|
||||||
self.event_id,
|
"sender": self.sender,
|
||||||
self.sender,
|
"origin_server_ts": self.origin_server_ts,
|
||||||
self.origin_server_ts,
|
"unsigned": self.unsigned,
|
||||||
serde_json::to_string(&self.unsigned).expect("Map::to_string always works"),
|
"state_key": self.state_key,
|
||||||
self.state_key
|
});
|
||||||
.as_ref()
|
|
||||||
.expect("state events have state keys")
|
|
||||||
);
|
|
||||||
|
|
||||||
Raw::from_json(
|
serde_json::from_value(json).expect("Raw::from_value always works")
|
||||||
serde_json::value::RawValue::from_string(json).expect("our string is valid json"),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
|
|
|
@ -685,7 +685,7 @@ fn handle_incoming_pdu<'a>(
|
||||||
) {
|
) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Drop
|
// Drop
|
||||||
error!("{:?}: {}", value, e);
|
warn!("{:?}: {}", value, e);
|
||||||
return Err("Signature verification failed".to_string());
|
return Err("Signature verification failed".to_string());
|
||||||
}
|
}
|
||||||
Ok(ruma::signatures::Verified::Signatures) => {
|
Ok(ruma::signatures::Verified::Signatures) => {
|
||||||
|
@ -1147,7 +1147,7 @@ pub(crate) async fn fetch_and_handle_events(
|
||||||
debug!("Got {} over federation: {:?}", id, res);
|
debug!("Got {} over federation: {:?}", id, res);
|
||||||
let (event_id, value) =
|
let (event_id, value) =
|
||||||
crate::pdu::gen_event_id_canonical_json(&res.pdu)?;
|
crate::pdu::gen_event_id_canonical_json(&res.pdu)?;
|
||||||
let pdu = handle_incoming_pdu(
|
let pdu = match handle_incoming_pdu(
|
||||||
origin,
|
origin,
|
||||||
&event_id,
|
&event_id,
|
||||||
value,
|
value,
|
||||||
|
@ -1157,14 +1157,20 @@ pub(crate) async fn fetch_and_handle_events(
|
||||||
auth_cache,
|
auth_cache,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
{
|
||||||
error!("Error: {:?}", e);
|
Ok(pdu) => pdu,
|
||||||
Error::Conflict("Authentication of event failed")
|
Err(e) => {
|
||||||
})?;
|
warn!("Authentication of event {} failed: {:?}", id, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pdu
|
pdu
|
||||||
}
|
}
|
||||||
Err(_) => return Err(Error::BadServerResponse("Failed to fetch event")),
|
Err(_) => {
|
||||||
|
warn!("Failed to fetch event: {}", id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1665,10 +1671,9 @@ pub async fn fetch_required_signing_keys(
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(keys) => keys,
|
Ok(keys) => keys,
|
||||||
Err(e) => {
|
Err(_) => {
|
||||||
return Err(Error::BadServerResponse(
|
warn!("Signature verification failed: Could not fetch signing key.",);
|
||||||
"Signature verification failed: Could not fetch signing key.",
|
continue;
|
||||||
));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue