Skip to content
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

Support MSC4040 matrix-fed service name lookup #142

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

turt2live
Copy link
Member

@turt2live turt2live commented Aug 19, 2023

See matrix-org/matrix-spec#1624

Requires matrix-org/gomatrixserverlib#411

Domain tests:

3c.s.resolvematrix.dev - _matrix only, .well-known

image

4.s.resolvematrix.dev - _matrix only

image

3c.msc4040.s.resolvematrix.dev - _matrix-fed only, .well-known

image

4.msc4040.s.resolvematrix.dev - _matrix-fed only

image

t2l.io - _matrix-fed and _matrix fallback

(TODO: Update resolvematrix.dev to support this case)

image

go.mod Outdated Show resolved Hide resolved
devonh added a commit to matrix-org/gomatrixserverlib that referenced this pull request Aug 22, 2023
Comment on lines +631 to +648
// isValidCertificate is sourced from an old version of gomatrixserverlib
func isValidCertificate(serverName spec.ServerName, c *x509.Certificate, intermediates *x509.CertPool) (valid bool, err error) {
host, _, isValid := spec.ParseAndValidateServerName(serverName)
if !isValid {
err = fmt.Errorf("%q is not a valid serverName", serverName)
return false, err
}

// Check certificate chain validity
verificationOpts := x509.VerifyOptions{
// Certificate.Verify appears to handle IP addresses optionally surrounded by square brackets.
DNSName: host,
Intermediates: intermediates,
}
roots, err := c.Verify(verificationOpts)

return len(roots) > 0, err
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me a bit nervous, it seems it was removed in matrix-org/gomatrixserverlib#364 and added in matrix-org/gomatrixserverlib@5a698c3 and never used anywhere (except here?)

tl;dr Is there a standard go way to validate the certificate instead of custom code like this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw, here is how I do it in MMR (another Go project).

The block of code added in the PR here was mostly out of fear: it felt particularly magic, and I wasn't super interested in debugging too much of the federation tester 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we're just doing this for informational purposes, I think this is OK. I mean, it also looks sane (but looks can be deceiving).
I can't see how you'd really knock any of this off — you need to be able to specify the DNS name and any intermediate certs. From recent experience working with X.509 I'd say it looks decent. But even if I was wrong, the worst we'll do is show the wrong result in the tester? I don't feel a grand need to worry too much.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these changes are just from bumping the gomatrixserverlib used, I think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes - should be its own commit

@clokep clokep requested a review from a team August 24, 2023 20:01
Co-authored-by: Sandro <sandro.jaeckel@gmail.com>
Comment on lines +376 to +383
// Append the deprecated ones too
cname, records, err2 := net.LookupSRV("matrix", "tcp", string(serverName))
if result.SRVCName == "" {
result.SRVCName = cname
}
if records != nil {
result.SRVRecords = append(result.SRVRecords, records...)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this really make sense? I suspect it would be better to return it in a different field and update the UI to show reasonable information about the legacy vs. new ones.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning a new field felt sufficiently complicated, for reasons I don't remember. I agree that a new field would be best.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the UI tool be able to distinguish the two different types of SRV records based on this info?

I think a new field could possibly be best too, but either way I would like to ensure the information is there.

(Maybe you kind of want the result to be a warning of some sort if only the legacy option is set...)

@clokep clokep requested a review from a team December 4, 2023 18:11
Copy link
Contributor

@reivilibre reivilibre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall looks OK to me. If you can address the field separation that would be good, otherwise it'd be nice to have a start at least I think, if the client UI can distinguish both cases anyway.

Comment on lines +631 to +648
// isValidCertificate is sourced from an old version of gomatrixserverlib
func isValidCertificate(serverName spec.ServerName, c *x509.Certificate, intermediates *x509.CertPool) (valid bool, err error) {
host, _, isValid := spec.ParseAndValidateServerName(serverName)
if !isValid {
err = fmt.Errorf("%q is not a valid serverName", serverName)
return false, err
}

// Check certificate chain validity
verificationOpts := x509.VerifyOptions{
// Certificate.Verify appears to handle IP addresses optionally surrounded by square brackets.
DNSName: host,
Intermediates: intermediates,
}
roots, err := c.Verify(verificationOpts)

return len(roots) > 0, err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we're just doing this for informational purposes, I think this is OK. I mean, it also looks sane (but looks can be deceiving).
I can't see how you'd really knock any of this off — you need to be able to specify the DNS name and any intermediate certs. From recent experience working with X.509 I'd say it looks decent. But even if I was wrong, the worst we'll do is show the wrong result in the tester? I don't feel a grand need to worry too much.

Comment on lines +376 to +383
// Append the deprecated ones too
cname, records, err2 := net.LookupSRV("matrix", "tcp", string(serverName))
if result.SRVCName == "" {
result.SRVCName = cname
}
if records != nil {
result.SRVRecords = append(result.SRVRecords, records...)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the UI tool be able to distinguish the two different types of SRV records based on this info?

I think a new field could possibly be best too, but either way I would like to ensure the information is there.

(Maybe you kind of want the result to be a warning of some sort if only the legacy option is set...)

@turt2live
Copy link
Member Author

This PR may need taking over from someone on the maintenance side, sorry. This PR is becoming fairly critical to deploy, but I'm running out of spare time to push it forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants