-
-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
server-util: Use http-auth crate to parse XMatrix #1805
base: main
Are you sure you want to change the base?
Conversation
For finding the XMatrix challenge, would it be better to replace ruma/crates/ruma-server-util/src/authorization.rs Lines 50 to 63 in c50064a
with let Some(xmatrix) = parser
.into_iter()
.filter_map(Result::ok)
.find(|challenge| challenge.scheme == XMatrix::SCHEME)
else {
return Err(XMatrixParseError::NotFound);
};
This should be handled by |
Thanks for the review! Next time, could you leave your comments directly on the code? It's often easier to have discussions in threads. Indeed, we could simplify it. Sometimes I find chains hard to follow but here it should be fine.
Is that a thing we should support? I don't think it was supported before. I don't see anything about it in the spec. http-auth returns a |
So the reason I didn't do a chain is actually because we want to return any parser error we get, which your chain doesn't do. Ideally we would need |
You probably want to call |
I think that's about it, everything else looks good. 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I am not sure how we should be handling multiple X-Matrix challenges, or if http-auth will do that for us.
Is that a thing we should support? I don't think it was supported before. I don't see anything about it in the spec. http-auth returns a Vec so I assume it doesn't try to deduplicate schemes, but we only handle the first one in the list.
According to MSC4029, we should validate that all X-Matrix
signatures are valid. It is currently just an MSC though, so we don't have to follow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you could in theory have several key
and sig
. I don't know what format Synapse supports (according to the MSC).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but the thing is that this method can only used to extract a single header (since it only parses the value, i.e. not Authorization
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could have (which afaiu is supported by the RFC):
X-Matrix origin="yours.org",destination="mine.org",key="key1",sig="sig1",key="key2",sig="sig2"
Or if what Synapse does is support several challenges in the value (even if it's not supported in the Authorization
header according to the RFC), it could be:
X-Matrix origin="yours.org",destination="mine.org",key="key1",sig="sig1", X-Matrix origin="yours.org",destination="mine.org",key="key2",sig="sig2"
Both are still a single header value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe the latter is though. 🤔
The latter is supported on WWW-Authenticate
, but not on Authorization
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No the latter isn't, not for the Authorization
header. In any case, if the MSC says that Synapse supports several signatures, it must not be RFC-compliant. The only RFC-compliant way to have one would be to have a list inside the value of the parameter, but then that is not a backwards-compatible change.
In any case, as long as the MSC is not clearer about the syntax, I believe we should just handle the first credentials we see, and ignore other ones for now for forwards-compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added another comment to the MSC, to ask how this would possibly occur.
Woops I had forgotten to push the commit. |
I was wondering if that was the case, or if you were just waiting to resolve the last thread. 😅 |
} | ||
.try_into() | ||
.expect("header format is static") | ||
self.try_into().expect("header format is static") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sig
value could violate these conditions, should we make a new type for it so it can be validated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example:
#[test]
fn xmatrix_auth_1_3_extended_ascii() {
let header = HeaderValue::from_static("X-Matrix origin=\"origin.hs.example.com\" , destination=\"destination.hs.example.com\",key=\"ed25519:key1\", sig=\"ABCDEFÇ...\"");
let credentials = XMatrix::try_from(&header).unwrap();
assert_eq!(credentials.origin, "origin.hs.example.com");
assert_eq!(credentials.destination.unwrap(), "destination.hs.example.com");
assert_eq!(credentials.key, "ed25519:key1");
assert_eq!(credentials.sig, "ABCDEFÇ...");
}
---- authorization::tests::xmatrix_auth_1_3_extended_ascii stdout ----
thread 'authorization::tests::xmatrix_auth_1_3_extended_ascii' panicked at /home/alpha/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/http-1.1.0/src/header/value.rs:95:17:
index out of bounds: the len is 0 but the index is 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
authorization::tests::xmatrix_auth_1_3_extended_ascii
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: once we ensure that the conversion cannot fail, we should probably switch the TryFrom
to From
, and then move the expect()
in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm not sure anymore, since the following passes fine:
#[test]
fn xmatrix_auth_1_3_extended_ascii() {
let creds = XMatrix {
origin: "origin.hs.example.com".try_into().unwrap(),
destination: Some("destination.hs.example.com".try_into().unwrap()),
key: "ed25519:key1".try_into().unwrap(),
sig: "ABCDEFÇ...".to_owned(),
};
let _header = creds.encode();
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like it is escaped (when?):
"X-Matrix destination=\"destination.hs.example.com\",key=\"ed25519:key1\",origin=\"origin.hs.example.com\",sig=\"ABCDEF\xc3\x87...\""
So is there a reason to have an expect()
in encode
instead of just moving it to From
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see any evidence of escaping there, that's just String
's Debug
implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, seems you are correct, my bad.
This breaks unquoted colons in values, which the spec says should be supported, and which were explicitly supported with the previous parser:
It also doesn't escape quotes and backslashes in quoted fields, solved by #1830. The test case from #1830 covers both issues: |
About the colon issue, see #1805 (comment) And yeah you seem to be right about the escaping. |
Fixes #1801.