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)
This commit is contained in:
		
							parent
							
								
									8b40e0a85f
								
							
						
					
					
						commit
						5951294638
					
				
					 5 changed files with 48 additions and 33 deletions
				
			
		
							
								
								
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -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 a new issue