Update gomatrixserverlib (#90)
parent
0309035aad
commit
a56f609b74
|
@ -22,7 +22,7 @@ import (
|
||||||
// ClientAPI contains the config information necessary to spin up a clientapi process.
|
// ClientAPI contains the config information necessary to spin up a clientapi process.
|
||||||
type ClientAPI struct {
|
type ClientAPI struct {
|
||||||
// The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
|
// The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
|
||||||
ServerName string
|
ServerName gomatrixserverlib.ServerName
|
||||||
// The private key which will be used to sign events.
|
// The private key which will be used to sign events.
|
||||||
PrivateKey ed25519.PrivateKey
|
PrivateKey ed25519.PrivateKey
|
||||||
// An arbitrary string used to uniquely identify the PrivateKey. Must start with the
|
// An arbitrary string used to uniquely identify the PrivateKey. Must start with the
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/config"
|
"github.com/matrix-org/dendrite/clientapi/config"
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
@ -40,7 +41,7 @@ type passwordRequest struct {
|
||||||
type loginResponse struct {
|
type loginResponse struct {
|
||||||
UserID string `json:"user_id"`
|
UserID string `json:"user_id"`
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
HomeServer string `json:"home_server"`
|
HomeServer gomatrixserverlib.ServerName `json:"home_server"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func passwordLogin() loginFlows {
|
func passwordLogin() loginFlows {
|
||||||
|
@ -85,6 +86,6 @@ func Login(req *http.Request, cfg config.ClientAPI) util.JSONResponse {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeUserID(localpart, domain string) string {
|
func makeUserID(localpart string, domain gomatrixserverlib.ServerName) string {
|
||||||
return fmt.Sprintf("@%s:%s", localpart, domain)
|
return fmt.Sprintf("@%s:%s", localpart, domain)
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,10 @@ func buildAndOutput() gomatrixserverlib.EventReference {
|
||||||
eventID++
|
eventID++
|
||||||
id := fmt.Sprintf("$%d:%s", eventID, *serverName)
|
id := fmt.Sprintf("$%d:%s", eventID, *serverName)
|
||||||
now = time.Unix(0, 0)
|
now = time.Unix(0, 0)
|
||||||
event, err := b.Build(id, now, *serverName, gomatrixserverlib.KeyID(*keyID), privateKey)
|
name := gomatrixserverlib.ServerName(*serverName)
|
||||||
|
key := gomatrixserverlib.KeyID(*keyID)
|
||||||
|
|
||||||
|
event, err := b.Build(id, now, name, key, privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
{
|
{
|
||||||
"importpath": "github.com/matrix-org/gomatrixserverlib",
|
"importpath": "github.com/matrix-org/gomatrixserverlib",
|
||||||
"repository": "https://github.com/matrix-org/gomatrixserverlib",
|
"repository": "https://github.com/matrix-org/gomatrixserverlib",
|
||||||
"revision": "fd3b9faf8492989e8f782592d37dcbdc01c44fea",
|
"revision": "9c075cb699ceb64cacd9136a0e7a0e0ff3dc9bcf",
|
||||||
"branch": "master"
|
"branch": "master"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,8 +84,8 @@ func makeHTTPSURL(u *url.URL, addr string) (httpsURL url.URL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *federationTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
func (f *federationTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
host := r.URL.Host
|
serverName := ServerName(r.URL.Host)
|
||||||
dnsResult, err := LookupServer(host)
|
dnsResult, err := LookupServer(serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -98,15 +98,15 @@ func (f *federationTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no address found for matrix host %v", host)
|
return nil, fmt.Errorf("no address found for matrix host %v", serverName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupUserInfo gets information about a user from a given matrix homeserver
|
// LookupUserInfo gets information about a user from a given matrix homeserver
|
||||||
// using a bearer access token.
|
// using a bearer access token.
|
||||||
func (fc *Client) LookupUserInfo(matrixServer, token string) (u UserInfo, err error) {
|
func (fc *Client) LookupUserInfo(matrixServer ServerName, token string) (u UserInfo, err error) {
|
||||||
url := url.URL{
|
url := url.URL{
|
||||||
Scheme: "matrix",
|
Scheme: "matrix",
|
||||||
Host: matrixServer,
|
Host: string(matrixServer),
|
||||||
Path: "/_matrix/federation/v1/openid/userinfo",
|
Path: "/_matrix/federation/v1/openid/userinfo",
|
||||||
RawQuery: url.Values{"access_token": []string{token}}.Encode(),
|
RawQuery: url.Values{"access_token": []string{token}}.Encode(),
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ func (fc *Client) LookupUserInfo(matrixServer, token string) (u UserInfo, err er
|
||||||
}
|
}
|
||||||
|
|
||||||
userParts := strings.SplitN(u.Sub, ":", 2)
|
userParts := strings.SplitN(u.Sub, ":", 2)
|
||||||
if len(userParts) != 2 || userParts[1] != matrixServer {
|
if len(userParts) != 2 || userParts[1] != string(matrixServer) {
|
||||||
err = fmt.Errorf("userID doesn't match server name '%v' != '%v'", u.Sub, matrixServer)
|
err = fmt.Errorf("userID doesn't match server name '%v' != '%v'", u.Sub, matrixServer)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -153,11 +153,11 @@ func (fc *Client) LookupUserInfo(matrixServer, token string) (u UserInfo, err er
|
||||||
// copy of the keys.
|
// copy of the keys.
|
||||||
// Returns the keys or an error if there was a problem talking to the server.
|
// Returns the keys or an error if there was a problem talking to the server.
|
||||||
func (fc *Client) LookupServerKeys(
|
func (fc *Client) LookupServerKeys(
|
||||||
matrixServer string, keyRequests map[PublicKeyRequest]Timestamp,
|
matrixServer ServerName, keyRequests map[PublicKeyRequest]Timestamp,
|
||||||
) (map[PublicKeyRequest]ServerKeys, error) {
|
) (map[PublicKeyRequest]ServerKeys, error) {
|
||||||
url := url.URL{
|
url := url.URL{
|
||||||
Scheme: "matrix",
|
Scheme: "matrix",
|
||||||
Host: matrixServer,
|
Host: string(matrixServer),
|
||||||
Path: "/_matrix/key/v2/query",
|
Path: "/_matrix/key/v2/query",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,8 +167,8 @@ func (fc *Client) LookupServerKeys(
|
||||||
MinimumValidUntilTS Timestamp `json:"minimum_valid_until_ts"`
|
MinimumValidUntilTS Timestamp `json:"minimum_valid_until_ts"`
|
||||||
}
|
}
|
||||||
request := struct {
|
request := struct {
|
||||||
ServerKeyMap map[string]map[KeyID]keyreq `json:"server_keys"`
|
ServerKeyMap map[ServerName]map[KeyID]keyreq `json:"server_keys"`
|
||||||
}{map[string]map[KeyID]keyreq{}}
|
}{map[ServerName]map[KeyID]keyreq{}}
|
||||||
for k, ts := range keyRequests {
|
for k, ts := range keyRequests {
|
||||||
server := request.ServerKeyMap[k.ServerName]
|
server := request.ServerKeyMap[k.ServerName]
|
||||||
if server == nil {
|
if server == nil {
|
||||||
|
|
|
@ -109,14 +109,14 @@ var emptyEventReferenceList = []EventReference{}
|
||||||
// Call this after filling out the necessary fields.
|
// Call this after filling out the necessary fields.
|
||||||
// This can be called mutliple times on the same builder.
|
// This can be called mutliple times on the same builder.
|
||||||
// A different event ID must be supplied each time this is called.
|
// A different event ID must be supplied each time this is called.
|
||||||
func (eb *EventBuilder) Build(eventID string, now time.Time, origin string, keyID KeyID, privateKey ed25519.PrivateKey) (result Event, err error) {
|
func (eb *EventBuilder) Build(eventID string, now time.Time, origin ServerName, keyID KeyID, privateKey ed25519.PrivateKey) (result Event, err error) {
|
||||||
var event struct {
|
var event struct {
|
||||||
EventBuilder
|
EventBuilder
|
||||||
EventID string `json:"event_id"`
|
EventID string `json:"event_id"`
|
||||||
RawContent rawJSON `json:"content"`
|
RawContent rawJSON `json:"content"`
|
||||||
RawUnsigned rawJSON `json:"unsigned,omitempty"`
|
RawUnsigned rawJSON `json:"unsigned,omitempty"`
|
||||||
OriginServerTS Timestamp `json:"origin_server_ts"`
|
OriginServerTS Timestamp `json:"origin_server_ts"`
|
||||||
Origin string `json:"origin"`
|
Origin ServerName `json:"origin"`
|
||||||
}
|
}
|
||||||
event.EventBuilder = *eb
|
event.EventBuilder = *eb
|
||||||
if event.PrevEvents == nil {
|
if event.PrevEvents == nil {
|
||||||
|
@ -143,7 +143,7 @@ func (eb *EventBuilder) Build(eventID string, now time.Time, origin string, keyI
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if eventJSON, err = signEvent(origin, keyID, privateKey, eventJSON); err != nil {
|
if eventJSON, err = signEvent(string(origin), keyID, privateKey, eventJSON); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
// A PublicKeyRequest is a request for a public key with a particular key ID.
|
// A PublicKeyRequest is a request for a public key with a particular key ID.
|
||||||
type PublicKeyRequest struct {
|
type PublicKeyRequest struct {
|
||||||
// The server to fetch a key for.
|
// The server to fetch a key for.
|
||||||
ServerName string
|
ServerName ServerName
|
||||||
// The ID of the key to fetch.
|
// The ID of the key to fetch.
|
||||||
KeyID KeyID
|
KeyID KeyID
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ type KeyRing struct {
|
||||||
// signature from that server.
|
// signature from that server.
|
||||||
type VerifyJSONRequest struct {
|
type VerifyJSONRequest struct {
|
||||||
// The name of the matrix server to check for a signature for.
|
// The name of the matrix server to check for a signature for.
|
||||||
ServerName string
|
ServerName ServerName
|
||||||
// The millisecond posix timestamp the message needs to be valid at.
|
// The millisecond posix timestamp the message needs to be valid at.
|
||||||
AtTS Timestamp
|
AtTS Timestamp
|
||||||
// The JSON bytes.
|
// The JSON bytes.
|
||||||
|
@ -71,7 +71,7 @@ func (k *KeyRing) VerifyJSONs(requests []VerifyJSONRequest) ([]VerifyJSONResult,
|
||||||
keyIDs := make([][]KeyID, len(requests))
|
keyIDs := make([][]KeyID, len(requests))
|
||||||
|
|
||||||
for i := range requests {
|
for i := range requests {
|
||||||
ids, err := ListKeyIDs(requests[i].ServerName, requests[i].Message)
|
ids, err := ListKeyIDs(string(requests[i].ServerName), requests[i].Message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
results[i].Result = fmt.Errorf("gomatrixserverlib: error extracting key IDs")
|
results[i].Result = fmt.Errorf("gomatrixserverlib: error extracting key IDs")
|
||||||
continue
|
continue
|
||||||
|
@ -187,7 +187,7 @@ func (k *KeyRing) checkUsingKeys(
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := VerifyJSON(
|
if err := VerifyJSON(
|
||||||
requests[i].ServerName, keyID, ed25519.PublicKey(publicKey), requests[i].Message,
|
string(requests[i].ServerName), keyID, ed25519.PublicKey(publicKey), requests[i].Message,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
// The signature wasn't valid, record the error and try the next key ID.
|
// The signature wasn't valid, record the error and try the next key ID.
|
||||||
results[i].Result = err
|
results[i].Result = err
|
||||||
|
@ -203,7 +203,7 @@ func (k *KeyRing) checkUsingKeys(
|
||||||
// A PerspectiveKeyFetcher fetches server keys from a single perspective server.
|
// A PerspectiveKeyFetcher fetches server keys from a single perspective server.
|
||||||
type PerspectiveKeyFetcher struct {
|
type PerspectiveKeyFetcher struct {
|
||||||
// The name of the perspective server to fetch keys from.
|
// The name of the perspective server to fetch keys from.
|
||||||
PerspectiveServerName string
|
PerspectiveServerName ServerName
|
||||||
// The ed25519 public keys the perspective server must sign responses with.
|
// The ed25519 public keys the perspective server must sign responses with.
|
||||||
PerspectiveServerKeys map[KeyID]ed25519.PublicKey
|
PerspectiveServerKeys map[KeyID]ed25519.PublicKey
|
||||||
// The federation client to use to fetch keys with.
|
// The federation client to use to fetch keys with.
|
||||||
|
@ -219,7 +219,7 @@ func (p *PerspectiveKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestam
|
||||||
|
|
||||||
for req, keys := range results {
|
for req, keys := range results {
|
||||||
var valid bool
|
var valid bool
|
||||||
keyIDs, err := ListKeyIDs(p.PerspectiveServerName, keys.Raw)
|
keyIDs, err := ListKeyIDs(string(p.PerspectiveServerName), keys.Raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The response from the perspective server was corrupted.
|
// The response from the perspective server was corrupted.
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -230,7 +230,7 @@ func (p *PerspectiveKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestam
|
||||||
// We don't have a key for that keyID, skip to the next keyID.
|
// We don't have a key for that keyID, skip to the next keyID.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := VerifyJSON(p.PerspectiveServerName, keyID, perspectiveKey, keys.Raw); err != nil {
|
if err := VerifyJSON(string(p.PerspectiveServerName), keyID, perspectiveKey, keys.Raw); err != nil {
|
||||||
// An invalid signature is very bad since it means we have a
|
// An invalid signature is very bad since it means we have a
|
||||||
// problem talking to the perspective server.
|
// problem talking to the perspective server.
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -263,7 +263,7 @@ type DirectKeyFetcher struct {
|
||||||
|
|
||||||
// FetchKeys implements KeyFetcher
|
// FetchKeys implements KeyFetcher
|
||||||
func (d *DirectKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestamp) (map[PublicKeyRequest]ServerKeys, error) {
|
func (d *DirectKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestamp) (map[PublicKeyRequest]ServerKeys, error) {
|
||||||
byServer := map[string]map[PublicKeyRequest]Timestamp{}
|
byServer := map[ServerName]map[PublicKeyRequest]Timestamp{}
|
||||||
for req, ts := range requests {
|
for req, ts := range requests {
|
||||||
server := byServer[req.ServerName]
|
server := byServer[req.ServerName]
|
||||||
if server == nil {
|
if server == nil {
|
||||||
|
@ -289,7 +289,7 @@ func (d *DirectKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestamp) (m
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DirectKeyFetcher) fetchKeysForServer(
|
func (d *DirectKeyFetcher) fetchKeysForServer(
|
||||||
serverName string, requests map[PublicKeyRequest]Timestamp,
|
serverName ServerName, requests map[PublicKeyRequest]Timestamp,
|
||||||
) (map[PublicKeyRequest]ServerKeys, error) {
|
) (map[PublicKeyRequest]ServerKeys, error) {
|
||||||
results, err := d.Client.LookupServerKeys(serverName, requests)
|
results, err := d.Client.LookupServerKeys(serverName, requests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -27,13 +27,18 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A ServerName is the name a matrix homeserver is identified by.
|
||||||
|
// It is a DNS name without a trailing dot optionally followed by a port.
|
||||||
|
// So it has the format: "[0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*(:[0-9]+)?"
|
||||||
|
type ServerName string
|
||||||
|
|
||||||
// ServerKeys are the ed25519 signing keys published by a matrix server.
|
// ServerKeys are the ed25519 signing keys published by a matrix server.
|
||||||
// Contains SHA256 fingerprints of the TLS X509 certificates used by the server.
|
// Contains SHA256 fingerprints of the TLS X509 certificates used by the server.
|
||||||
type ServerKeys struct {
|
type ServerKeys struct {
|
||||||
// Copy of the raw JSON for signature checking.
|
// Copy of the raw JSON for signature checking.
|
||||||
Raw []byte
|
Raw []byte
|
||||||
// The server the raw JSON was downloaded from.
|
// The server the raw JSON was downloaded from.
|
||||||
FromServer string
|
FromServer ServerName
|
||||||
// The decoded JSON fields.
|
// The decoded JSON fields.
|
||||||
ServerKeyFields
|
ServerKeyFields
|
||||||
}
|
}
|
||||||
|
@ -59,7 +64,7 @@ type OldVerifyKey struct {
|
||||||
// ServerKeyFields are the parsed JSON contents of the ed25519 signing keys published by a matrix server.
|
// ServerKeyFields are the parsed JSON contents of the ed25519 signing keys published by a matrix server.
|
||||||
type ServerKeyFields struct {
|
type ServerKeyFields struct {
|
||||||
// The name of the server
|
// The name of the server
|
||||||
ServerName string `json:"server_name"`
|
ServerName ServerName `json:"server_name"`
|
||||||
// List of SHA256 fingerprints of X509 certificates used by this server.
|
// List of SHA256 fingerprints of X509 certificates used by this server.
|
||||||
TLSFingerprints []TLSFingerprint `json:"tls_fingerprints"`
|
TLSFingerprints []TLSFingerprint `json:"tls_fingerprints"`
|
||||||
// The current signing keys in use on this server.
|
// The current signing keys in use on this server.
|
||||||
|
@ -99,7 +104,7 @@ func (keys ServerKeys) PublicKey(keyID KeyID, atTS Timestamp) []byte {
|
||||||
// FetchKeysDirect fetches the matrix keys directly from the given address.
|
// FetchKeysDirect fetches the matrix keys directly from the given address.
|
||||||
// Optionally sets a SNI header if ``sni`` is not empty.
|
// Optionally sets a SNI header if ``sni`` is not empty.
|
||||||
// Returns the server keys and the state of the TLS connection used to retrieve them.
|
// Returns the server keys and the state of the TLS connection used to retrieve them.
|
||||||
func FetchKeysDirect(serverName, addr, sni string) (*ServerKeys, *tls.ConnectionState, error) {
|
func FetchKeysDirect(serverName ServerName, addr, sni string) (*ServerKeys, *tls.ConnectionState, error) {
|
||||||
// Create a TLS connection.
|
// Create a TLS connection.
|
||||||
tcpconn, err := net.Dial("tcp", addr)
|
tcpconn, err := net.Dial("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,7 +121,7 @@ func FetchKeysDirect(serverName, addr, sni string) (*ServerKeys, *tls.Connection
|
||||||
connectionState := tlsconn.ConnectionState()
|
connectionState := tlsconn.ConnectionState()
|
||||||
|
|
||||||
// Write a GET /_matrix/key/v2/server down the connection.
|
// Write a GET /_matrix/key/v2/server down the connection.
|
||||||
requestURL := "matrix://" + serverName + "/_matrix/key/v2/server"
|
requestURL := "matrix://" + string(serverName) + "/_matrix/key/v2/server"
|
||||||
request, err := http.NewRequest("GET", requestURL, nil)
|
request, err := http.NewRequest("GET", requestURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -169,7 +174,7 @@ type KeyChecks struct {
|
||||||
|
|
||||||
// CheckKeys checks the keys returned from a server to make sure they are valid.
|
// CheckKeys checks the keys returned from a server to make sure they are valid.
|
||||||
// If the checks pass then also return a map of key_id to Ed25519 public key and a list of SHA256 TLS fingerprints.
|
// If the checks pass then also return a map of key_id to Ed25519 public key and a list of SHA256 TLS fingerprints.
|
||||||
func CheckKeys(serverName string, now time.Time, keys ServerKeys, connState *tls.ConnectionState) (
|
func CheckKeys(serverName ServerName, now time.Time, keys ServerKeys, connState *tls.ConnectionState) (
|
||||||
checks KeyChecks, ed25519Keys map[KeyID]Base64String, sha256Fingerprints []Base64String,
|
checks KeyChecks, ed25519Keys map[KeyID]Base64String, sha256Fingerprints []Base64String,
|
||||||
) {
|
) {
|
||||||
checks.MatchingServerName = serverName == keys.ServerName
|
checks.MatchingServerName = serverName == keys.ServerName
|
||||||
|
@ -222,7 +227,7 @@ func checkVerifyKeys(keys ServerKeys, checks *KeyChecks) map[KeyID]Base64String
|
||||||
ValidEd25519: len(publicKey) == 32,
|
ValidEd25519: len(publicKey) == 32,
|
||||||
}
|
}
|
||||||
if entry.ValidEd25519 {
|
if entry.ValidEd25519 {
|
||||||
err := VerifyJSON(keys.ServerName, keyID, []byte(publicKey), keys.Raw)
|
err := VerifyJSON(string(keys.ServerName), keyID, []byte(publicKey), keys.Raw)
|
||||||
entry.MatchingSignature = err == nil
|
entry.MatchingSignature = err == nil
|
||||||
}
|
}
|
||||||
checks.Ed25519Checks[keyID] = entry
|
checks.Ed25519Checks[keyID] = entry
|
||||||
|
|
|
@ -21,11 +21,11 @@ type FederationRequest struct {
|
||||||
// specified in https://matrix.org/docs/spec/server_server/unstable.html#request-authentication
|
// specified in https://matrix.org/docs/spec/server_server/unstable.html#request-authentication
|
||||||
fields struct {
|
fields struct {
|
||||||
Content rawJSON `json:"content,omitempty"`
|
Content rawJSON `json:"content,omitempty"`
|
||||||
Destination string `json:"destination"`
|
Destination ServerName `json:"destination"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
Origin string `json:"origin"`
|
Origin ServerName `json:"origin"`
|
||||||
RequestURI string `json:"uri"`
|
RequestURI string `json:"uri"`
|
||||||
Signatures map[string]map[string]string `json:"signatures,omitempty"`
|
Signatures map[ServerName]map[KeyID]string `json:"signatures,omitempty"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ type FederationRequest struct {
|
||||||
// The destination is the name of a matrix homeserver.
|
// The destination is the name of a matrix homeserver.
|
||||||
// The request path must begin with a slash.
|
// The request path must begin with a slash.
|
||||||
// Eg. NewFederationRequest("GET", "matrix.org", "/_matrix/federation/v1/send/123")
|
// Eg. NewFederationRequest("GET", "matrix.org", "/_matrix/federation/v1/send/123")
|
||||||
func NewFederationRequest(method, destination, requestURI string) FederationRequest {
|
func NewFederationRequest(method string, destination ServerName, requestURI string) FederationRequest {
|
||||||
var r FederationRequest
|
var r FederationRequest
|
||||||
r.fields.Destination = destination
|
r.fields.Destination = destination
|
||||||
r.fields.Method = strings.ToUpper(method)
|
r.fields.Method = strings.ToUpper(method)
|
||||||
|
@ -70,7 +70,7 @@ func (r *FederationRequest) Content() []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Origin returns the server that the request originated on.
|
// Origin returns the server that the request originated on.
|
||||||
func (r *FederationRequest) Origin() string {
|
func (r *FederationRequest) Origin() ServerName {
|
||||||
return r.fields.Origin
|
return r.fields.Origin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ func (r *FederationRequest) RequestURI() string {
|
||||||
// Uses the algorithm specified https://matrix.org/docs/spec/server_server/unstable.html#request-authentication
|
// Uses the algorithm specified https://matrix.org/docs/spec/server_server/unstable.html#request-authentication
|
||||||
// Updates the request with the signature in place.
|
// Updates the request with the signature in place.
|
||||||
// Returns an error if there was a problem signing the request.
|
// Returns an error if there was a problem signing the request.
|
||||||
func (r *FederationRequest) Sign(serverName string, keyID KeyID, privateKey ed25519.PrivateKey) error {
|
func (r *FederationRequest) Sign(serverName ServerName, keyID KeyID, privateKey ed25519.PrivateKey) error {
|
||||||
if r.fields.Origin != "" && r.fields.Origin != serverName {
|
if r.fields.Origin != "" && r.fields.Origin != serverName {
|
||||||
return fmt.Errorf("gomatrixserverlib: the request is already signed by a different server")
|
return fmt.Errorf("gomatrixserverlib: the request is already signed by a different server")
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ func (r *FederationRequest) Sign(serverName string, keyID KeyID, privateKey ed25
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
signedData, err := SignJSON(serverName, keyID, privateKey, data)
|
signedData, err := SignJSON(string(serverName), keyID, privateKey, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -135,10 +135,10 @@ func (r *FederationRequest) HTTPRequest() (*http.Request, error) {
|
||||||
// Check that we can safely include the origin and key ID in the header.
|
// Check that we can safely include the origin and key ID in the header.
|
||||||
// We don't need to check the signature since we already know that it is
|
// We don't need to check the signature since we already know that it is
|
||||||
// base64.
|
// base64.
|
||||||
if !isSafeInHTTPQuotedString(r.fields.Origin) {
|
if !isSafeInHTTPQuotedString(string(r.fields.Origin)) {
|
||||||
return nil, fmt.Errorf("gomatrixserverlib: Request Origin isn't safe to include in an HTTP header")
|
return nil, fmt.Errorf("gomatrixserverlib: Request Origin isn't safe to include in an HTTP header")
|
||||||
}
|
}
|
||||||
if !isSafeInHTTPQuotedString(keyID) {
|
if !isSafeInHTTPQuotedString(string(keyID)) {
|
||||||
return nil, fmt.Errorf("gomatrixserverlib: Request key ID isn't safe to include in an HTTP header")
|
return nil, fmt.Errorf("gomatrixserverlib: Request key ID isn't safe to include in an HTTP header")
|
||||||
}
|
}
|
||||||
httpReq.Header.Add("Authorization", fmt.Sprintf(
|
httpReq.Header.Add("Authorization", fmt.Sprintf(
|
||||||
|
@ -191,7 +191,7 @@ func isSafeInHTTPQuotedString(text string) bool {
|
||||||
// the query parameters, and the JSON content. In particular the version of
|
// the query parameters, and the JSON content. In particular the version of
|
||||||
// HTTP and the headers aren't protected by the signature.
|
// HTTP and the headers aren't protected by the signature.
|
||||||
func VerifyHTTPRequest(
|
func VerifyHTTPRequest(
|
||||||
req *http.Request, now time.Time, destination string, keys KeyRing,
|
req *http.Request, now time.Time, destination ServerName, keys KeyRing,
|
||||||
) (*FederationRequest, util.JSONResponse) {
|
) (*FederationRequest, util.JSONResponse) {
|
||||||
request, err := readHTTPRequest(req)
|
request, err := readHTTPRequest(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -268,7 +268,7 @@ func readHTTPRequest(req *http.Request) (*FederationRequest, error) {
|
||||||
}
|
}
|
||||||
result.fields.Origin = origin
|
result.fields.Origin = origin
|
||||||
if result.fields.Signatures == nil {
|
if result.fields.Signatures == nil {
|
||||||
result.fields.Signatures = map[string]map[string]string{origin: map[string]string{key: sig}}
|
result.fields.Signatures = map[ServerName]map[KeyID]string{origin: map[KeyID]string{key: sig}}
|
||||||
} else {
|
} else {
|
||||||
result.fields.Signatures[origin][key] = sig
|
result.fields.Signatures[origin][key] = sig
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ func readHTTPRequest(req *http.Request) (*FederationRequest, error) {
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAuthorization(header string) (scheme, origin, key, sig string) {
|
func parseAuthorization(header string) (scheme string, origin ServerName, key KeyID, sig string) {
|
||||||
parts := strings.SplitN(header, " ", 2)
|
parts := strings.SplitN(header, " ", 2)
|
||||||
scheme = parts[0]
|
scheme = parts[0]
|
||||||
if scheme != "X-Matrix" {
|
if scheme != "X-Matrix" {
|
||||||
|
@ -294,10 +294,10 @@ func parseAuthorization(header string) (scheme, origin, key, sig string) {
|
||||||
name := pair[0]
|
name := pair[0]
|
||||||
value := strings.Trim(pair[1], "\"")
|
value := strings.Trim(pair[1], "\"")
|
||||||
if name == "origin" {
|
if name == "origin" {
|
||||||
origin = value
|
origin = ServerName(value)
|
||||||
}
|
}
|
||||||
if name == "key" {
|
if name == "key" {
|
||||||
key = value
|
key = KeyID(value)
|
||||||
}
|
}
|
||||||
if name == "sig" {
|
if name == "sig" {
|
||||||
sig = value
|
sig = value
|
||||||
|
|
|
@ -38,15 +38,15 @@ type DNSResult struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupServer looks up a matrix server in DNS.
|
// LookupServer looks up a matrix server in DNS.
|
||||||
func LookupServer(serverName string) (*DNSResult, error) {
|
func LookupServer(serverName ServerName) (*DNSResult, error) {
|
||||||
var result DNSResult
|
var result DNSResult
|
||||||
result.Hosts = map[string]HostResult{}
|
result.Hosts = map[string]HostResult{}
|
||||||
|
|
||||||
hosts := map[string][]net.SRV{}
|
hosts := map[string][]net.SRV{}
|
||||||
if strings.Index(serverName, ":") == -1 {
|
if strings.Index(string(serverName), ":") == -1 {
|
||||||
// If there isn't an explicit port set then try to look up the SRV record.
|
// If there isn't an explicit port set then try to look up the SRV record.
|
||||||
var err error
|
var err error
|
||||||
result.SRVCName, result.SRVRecords, err = net.LookupSRV("matrix", "tcp", serverName)
|
result.SRVCName, result.SRVRecords, err = net.LookupSRV("matrix", "tcp", string(serverName))
|
||||||
result.SRVError = err
|
result.SRVError = err
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,8 +57,8 @@ func LookupServer(serverName string) (*DNSResult, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// If there isn't a SRV record in DNS then fallback to "serverName:8448".
|
// If there isn't a SRV record in DNS then fallback to "serverName:8448".
|
||||||
hosts[serverName] = []net.SRV{net.SRV{
|
hosts[string(serverName)] = []net.SRV{net.SRV{
|
||||||
Target: serverName,
|
Target: string(serverName),
|
||||||
Port: 8448,
|
Port: 8448,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func LookupServer(serverName string) (*DNSResult, error) {
|
||||||
} else {
|
} else {
|
||||||
// There is a explicit port set in the server name.
|
// There is a explicit port set in the server name.
|
||||||
// We don't need to look up any SRV records.
|
// We don't need to look up any SRV records.
|
||||||
host, portStr, err := net.SplitHostPort(serverName)
|
host, portStr, err := net.SplitHostPort(string(serverName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue