add some debug logging and misc cleanup to keys/signatures/upload

Signed-off-by: June Clementine Strawberry <june@3.dog>
This commit is contained in:
June Clementine Strawberry 2025-04-03 16:08:02 -04:00
parent 29d55b8036
commit 94b107b42b
4 changed files with 86 additions and 51 deletions

22
Cargo.lock generated
View file

@ -3654,7 +3654,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma" name = "ruma"
version = "0.10.1" version = "0.10.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"assign", "assign",
"js_int", "js_int",
@ -3674,7 +3674,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-appservice-api" name = "ruma-appservice-api"
version = "0.10.0" version = "0.10.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3686,7 +3686,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-client-api" name = "ruma-client-api"
version = "0.18.0" version = "0.18.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"assign", "assign",
@ -3709,7 +3709,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-common" name = "ruma-common"
version = "0.13.0" version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"base64 0.22.1", "base64 0.22.1",
@ -3741,7 +3741,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-events" name = "ruma-events"
version = "0.28.1" version = "0.28.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"indexmap 2.8.0", "indexmap 2.8.0",
@ -3766,7 +3766,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-federation-api" name = "ruma-federation-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"bytes", "bytes",
"headers", "headers",
@ -3788,7 +3788,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-identifiers-validation" name = "ruma-identifiers-validation"
version = "0.9.5" version = "0.9.5"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"thiserror 2.0.12", "thiserror 2.0.12",
@ -3797,7 +3797,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-identity-service-api" name = "ruma-identity-service-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3807,7 +3807,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-macros" name = "ruma-macros"
version = "0.13.0" version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"proc-macro-crate", "proc-macro-crate",
@ -3822,7 +3822,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-push-gateway-api" name = "ruma-push-gateway-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3834,7 +3834,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-signatures" name = "ruma-signatures"
version = "0.15.0" version = "0.15.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=0701341a2fd5a6ea74beada18d5974cc401a4fc1#0701341a2fd5a6ea74beada18d5974cc401a4fc1" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"ed25519-dalek", "ed25519-dalek",

View file

@ -350,7 +350,7 @@ version = "0.1.2"
[workspace.dependencies.ruma] [workspace.dependencies.ruma]
git = "https://github.com/girlbossceo/ruwuma" git = "https://github.com/girlbossceo/ruwuma"
#branch = "conduwuit-changes" #branch = "conduwuit-changes"
rev = "0701341a2fd5a6ea74beada18d5974cc401a4fc1" rev = "edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
features = [ features = [
"compat", "compat",
"rand", "rand",

View file

@ -9,7 +9,8 @@ use ruma::{
client::{ client::{
error::ErrorKind, error::ErrorKind,
keys::{ keys::{
claim_keys, get_key_changes, get_keys, upload_keys, upload_signatures, claim_keys, get_key_changes, get_keys, upload_keys,
upload_signatures::{self, v3::Failure},
upload_signing_keys, upload_signing_keys,
}, },
uiaa::{AuthFlow, AuthType, UiaaInfo}, uiaa::{AuthFlow, AuthType, UiaaInfo},
@ -308,53 +309,81 @@ async fn check_for_new_keys(
/// # `POST /_matrix/client/r0/keys/signatures/upload` /// # `POST /_matrix/client/r0/keys/signatures/upload`
/// ///
/// Uploads end-to-end key signatures from the sender user. /// Uploads end-to-end key signatures from the sender user.
///
/// TODO: clean this timo-code up more. tried to improve it a bit to stop
/// exploding the entire request on bad sigs, but needs way more work.
pub(crate) async fn upload_signatures_route( pub(crate) async fn upload_signatures_route(
State(services): State<crate::State>, State(services): State<crate::State>,
body: Ruma<upload_signatures::v3::Request>, body: Ruma<upload_signatures::v3::Request>,
) -> Result<upload_signatures::v3::Response> { ) -> Result<upload_signatures::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated"); use upload_signatures::v3::FailureErrorCode::*;
if body.signed_keys.is_empty() {
debug!("Empty signed_keys sent in key signature upload");
return Ok(upload_signatures::v3::Response::new());
}
let sender_user = body.sender_user();
let mut failures: BTreeMap<OwnedUserId, BTreeMap<String, Failure>> = BTreeMap::new();
let mut failure_reasons: BTreeMap<String, Failure> = BTreeMap::new();
let failure = Failure {
errcode: InvalidSignature,
error: String::new(),
};
for (user_id, keys) in &body.signed_keys { for (user_id, keys) in &body.signed_keys {
for (key_id, key) in keys { for (key_id, key) in keys {
let key = serde_json::to_value(key) let Ok(key) = serde_json::to_value(key)
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid key JSON"))?; .inspect_err(|e| debug_warn!(?key_id, "Invalid \"key\" JSON: {e}"))
else {
let mut failure = failure.clone();
failure.error = String::from("Invalid \"key\" JSON");
failure_reasons.insert(key_id.to_owned(), failure);
continue;
};
for signature in key let Some(signatures) = key.get("signatures") else {
.get("signatures") let mut failure = failure.clone();
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Missing signatures field."))? failure.error = String::from("Missing \"signatures\" field");
.get(sender_user.to_string()) failure_reasons.insert(key_id.to_owned(), failure);
.ok_or(Error::BadRequest( continue;
ErrorKind::InvalidParam, };
"Invalid user in signatures field.",
))?
.as_object()
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Invalid signature."))?
.clone()
{
// Signature validation?
let signature = (
signature.0,
signature
.1
.as_str()
.ok_or(Error::BadRequest(
ErrorKind::InvalidParam,
"Invalid signature value.",
))?
.to_owned(),
);
services let Some(sender_user_val) = signatures.get(sender_user.to_string()) else {
let mut failure = failure.clone();
failure.error = String::from("Invalid user in signatures field");
failure_reasons.insert(key_id.to_owned(), failure);
continue;
};
let Some(sender_user_object) = sender_user_val.as_object() else {
let mut failure = failure.clone();
failure.error = String::from("signatures field is not a JSON object");
failure_reasons.insert(key_id.to_owned(), failure);
continue;
};
for (signature, val) in sender_user_object.clone() {
let signature = (signature, val.to_string());
if let Err(e) = services
.users .users
.sign_key(user_id, key_id, signature, sender_user) .sign_key(user_id, key_id, signature, sender_user)
.await?; .await
.inspect_err(|e| debug_warn!("{e}"))
{
let mut failure = failure.clone();
failure.error = format!("Error signing key: {e}");
failure_reasons.insert(key_id.to_owned(), failure);
continue;
}
} }
} }
failures.insert(user_id.to_owned(), failure_reasons.clone());
} }
Ok(upload_signatures::v3::Response { Ok(upload_signatures::v3::Response { failures })
failures: BTreeMap::new(), // TODO: integrate
})
} }
/// # `POST /_matrix/client/r0/keys/changes` /// # `POST /_matrix/client/r0/keys/changes`

View file

@ -593,7 +593,7 @@ impl Service {
key_id: &str, key_id: &str,
signature: (String, String), signature: (String, String),
sender_id: &UserId, sender_id: &UserId,
) -> Result<()> { ) -> Result {
let key = (target_id, key_id); let key = (target_id, key_id);
let mut cross_signing_key: serde_json::Value = self let mut cross_signing_key: serde_json::Value = self
@ -601,21 +601,27 @@ impl Service {
.keyid_key .keyid_key
.qry(&key) .qry(&key)
.await .await
.map_err(|_| err!(Request(InvalidParam("Tried to sign nonexistent key."))))? .map_err(|_| err!(Request(InvalidParam("Tried to sign nonexistent key"))))?
.deserialized() .deserialized()
.map_err(|e| err!(Database("key in keyid_key is invalid. {e:?}")))?; .map_err(|e| err!(Database(debug_warn!("key in keyid_key is invalid: {e:?}"))))?;
let signatures = cross_signing_key let signatures = cross_signing_key
.get_mut("signatures") .get_mut("signatures")
.ok_or_else(|| err!(Database("key in keyid_key has no signatures field.")))? .ok_or_else(|| {
err!(Database(debug_warn!("key in keyid_key has no signatures field")))
})?
.as_object_mut() .as_object_mut()
.ok_or_else(|| err!(Database("key in keyid_key has invalid signatures field.")))? .ok_or_else(|| {
err!(Database(debug_warn!("key in keyid_key has invalid signatures field.")))
})?
.entry(sender_id.to_string()) .entry(sender_id.to_string())
.or_insert_with(|| serde_json::Map::new().into()); .or_insert_with(|| serde_json::Map::new().into());
signatures signatures
.as_object_mut() .as_object_mut()
.ok_or_else(|| err!(Database("signatures in keyid_key for a user is invalid.")))? .ok_or_else(|| {
err!(Database(debug_warn!("signatures in keyid_key for a user is invalid.")))
})?
.insert(signature.0, signature.1.into()); .insert(signature.0, signature.1.into());
let key = (target_id, key_id); let key = (target_id, key_id);