From a56f609b745c59abe975c1ebe9e6ae0fc358fef7 Mon Sep 17 00:00:00 2001 From: Mark Haines Date: Fri, 5 May 2017 17:43:42 +0100 Subject: [PATCH] Update gomatrixserverlib (#90) --- .../dendrite/clientapi/config/config.go | 2 +- .../dendrite/clientapi/readers/login.go | 9 ++--- .../dendrite/cmd/create-room-events/main.go | 5 ++- vendor/manifest | 2 +- .../matrix-org/gomatrixserverlib/client.go | 20 +++++------ .../matrix-org/gomatrixserverlib/event.go | 14 ++++---- .../matrix-org/gomatrixserverlib/keyring.go | 18 +++++----- .../matrix-org/gomatrixserverlib/keys.go | 17 ++++++---- .../matrix-org/gomatrixserverlib/request.go | 34 +++++++++---------- .../matrix-org/gomatrixserverlib/resolve.go | 12 +++---- 10 files changed, 71 insertions(+), 62 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/config/config.go b/src/github.com/matrix-org/dendrite/clientapi/config/config.go index db5815f9..c5e846ec 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/config/config.go +++ b/src/github.com/matrix-org/dendrite/clientapi/config/config.go @@ -22,7 +22,7 @@ import ( // ClientAPI contains the config information necessary to spin up a clientapi process. type ClientAPI struct { // 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. PrivateKey ed25519.PrivateKey // An arbitrary string used to uniquely identify the PrivateKey. Must start with the diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go index 862b7e80..75df276a 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go @@ -19,6 +19,7 @@ import ( "github.com/matrix-org/dendrite/clientapi/config" "github.com/matrix-org/dendrite/clientapi/httputil" "github.com/matrix-org/dendrite/clientapi/jsonerror" + "github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/util" "net/http" ) @@ -38,9 +39,9 @@ type passwordRequest struct { } type loginResponse struct { - UserID string `json:"user_id"` - AccessToken string `json:"access_token"` - HomeServer string `json:"home_server"` + UserID string `json:"user_id"` + AccessToken string `json:"access_token"` + HomeServer gomatrixserverlib.ServerName `json:"home_server"` } 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) } diff --git a/src/github.com/matrix-org/dendrite/cmd/create-room-events/main.go b/src/github.com/matrix-org/dendrite/cmd/create-room-events/main.go index c9b2c599..ff949d3e 100644 --- a/src/github.com/matrix-org/dendrite/cmd/create-room-events/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/create-room-events/main.go @@ -111,7 +111,10 @@ func buildAndOutput() gomatrixserverlib.EventReference { eventID++ id := fmt.Sprintf("$%d:%s", eventID, *serverName) 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 { panic(err) } diff --git a/vendor/manifest b/vendor/manifest index 0bb2e207..35d58db8 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -92,7 +92,7 @@ { "importpath": "github.com/matrix-org/gomatrixserverlib", "repository": "https://github.com/matrix-org/gomatrixserverlib", - "revision": "fd3b9faf8492989e8f782592d37dcbdc01c44fea", + "revision": "9c075cb699ceb64cacd9136a0e7a0e0ff3dc9bcf", "branch": "master" }, { diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/client.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/client.go index fe47f04d..51bd8d0b 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/client.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/client.go @@ -84,8 +84,8 @@ func makeHTTPSURL(u *url.URL, addr string) (httpsURL url.URL) { } func (f *federationTripper) RoundTrip(r *http.Request) (*http.Response, error) { - host := r.URL.Host - dnsResult, err := LookupServer(host) + serverName := ServerName(r.URL.Host) + dnsResult, err := LookupServer(serverName) if err != nil { return nil, err } @@ -98,15 +98,15 @@ func (f *federationTripper) RoundTrip(r *http.Request) (*http.Response, error) { 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 // 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{ Scheme: "matrix", - Host: matrixServer, + Host: string(matrixServer), Path: "/_matrix/federation/v1/openid/userinfo", 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) - 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) return } @@ -153,11 +153,11 @@ func (fc *Client) LookupUserInfo(matrixServer, token string) (u UserInfo, err er // copy of the keys. // Returns the keys or an error if there was a problem talking to the server. func (fc *Client) LookupServerKeys( - matrixServer string, keyRequests map[PublicKeyRequest]Timestamp, + matrixServer ServerName, keyRequests map[PublicKeyRequest]Timestamp, ) (map[PublicKeyRequest]ServerKeys, error) { url := url.URL{ Scheme: "matrix", - Host: matrixServer, + Host: string(matrixServer), Path: "/_matrix/key/v2/query", } @@ -167,8 +167,8 @@ func (fc *Client) LookupServerKeys( MinimumValidUntilTS Timestamp `json:"minimum_valid_until_ts"` } request := struct { - ServerKeyMap map[string]map[KeyID]keyreq `json:"server_keys"` - }{map[string]map[KeyID]keyreq{}} + ServerKeyMap map[ServerName]map[KeyID]keyreq `json:"server_keys"` + }{map[ServerName]map[KeyID]keyreq{}} for k, ts := range keyRequests { server := request.ServerKeyMap[k.ServerName] if server == nil { diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/event.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/event.go index ddb5e057..d125c883 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/event.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/event.go @@ -109,14 +109,14 @@ var emptyEventReferenceList = []EventReference{} // Call this after filling out the necessary fields. // This can be called mutliple times on the same builder. // 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 { EventBuilder - EventID string `json:"event_id"` - RawContent rawJSON `json:"content"` - RawUnsigned rawJSON `json:"unsigned,omitempty"` - OriginServerTS Timestamp `json:"origin_server_ts"` - Origin string `json:"origin"` + EventID string `json:"event_id"` + RawContent rawJSON `json:"content"` + RawUnsigned rawJSON `json:"unsigned,omitempty"` + OriginServerTS Timestamp `json:"origin_server_ts"` + Origin ServerName `json:"origin"` } event.EventBuilder = *eb if event.PrevEvents == nil { @@ -143,7 +143,7 @@ func (eb *EventBuilder) Build(eventID string, now time.Time, origin string, keyI return } - if eventJSON, err = signEvent(origin, keyID, privateKey, eventJSON); err != nil { + if eventJSON, err = signEvent(string(origin), keyID, privateKey, eventJSON); err != nil { return } diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/keyring.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/keyring.go index dbe5f9d9..cea6aa5d 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/keyring.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/keyring.go @@ -10,7 +10,7 @@ import ( // A PublicKeyRequest is a request for a public key with a particular key ID. type PublicKeyRequest struct { // The server to fetch a key for. - ServerName string + ServerName ServerName // The ID of the key to fetch. KeyID KeyID } @@ -46,7 +46,7 @@ type KeyRing struct { // signature from that server. type VerifyJSONRequest struct { // 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. AtTS Timestamp // The JSON bytes. @@ -71,7 +71,7 @@ func (k *KeyRing) VerifyJSONs(requests []VerifyJSONRequest) ([]VerifyJSONResult, keyIDs := make([][]KeyID, len(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 { results[i].Result = fmt.Errorf("gomatrixserverlib: error extracting key IDs") continue @@ -187,7 +187,7 @@ func (k *KeyRing) checkUsingKeys( continue } 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 { // The signature wasn't valid, record the error and try the next key ID. results[i].Result = err @@ -203,7 +203,7 @@ func (k *KeyRing) checkUsingKeys( // A PerspectiveKeyFetcher fetches server keys from a single perspective server. type PerspectiveKeyFetcher struct { // 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. PerspectiveServerKeys map[KeyID]ed25519.PublicKey // 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 { var valid bool - keyIDs, err := ListKeyIDs(p.PerspectiveServerName, keys.Raw) + keyIDs, err := ListKeyIDs(string(p.PerspectiveServerName), keys.Raw) if err != nil { // The response from the perspective server was corrupted. 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. 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 // problem talking to the perspective server. return nil, err @@ -263,7 +263,7 @@ type DirectKeyFetcher struct { // FetchKeys implements KeyFetcher 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 { server := byServer[req.ServerName] if server == nil { @@ -289,7 +289,7 @@ func (d *DirectKeyFetcher) FetchKeys(requests map[PublicKeyRequest]Timestamp) (m } func (d *DirectKeyFetcher) fetchKeysForServer( - serverName string, requests map[PublicKeyRequest]Timestamp, + serverName ServerName, requests map[PublicKeyRequest]Timestamp, ) (map[PublicKeyRequest]ServerKeys, error) { results, err := d.Client.LookupServerKeys(serverName, requests) if err != nil { diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/keys.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/keys.go index 52889864..ffd57e59 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/keys.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/keys.go @@ -27,13 +27,18 @@ import ( "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. // Contains SHA256 fingerprints of the TLS X509 certificates used by the server. type ServerKeys struct { // Copy of the raw JSON for signature checking. Raw []byte // The server the raw JSON was downloaded from. - FromServer string + FromServer ServerName // The decoded JSON fields. ServerKeyFields } @@ -59,7 +64,7 @@ type OldVerifyKey struct { // ServerKeyFields are the parsed JSON contents of the ed25519 signing keys published by a matrix server. type ServerKeyFields struct { // 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. TLSFingerprints []TLSFingerprint `json:"tls_fingerprints"` // 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. // 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. -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. tcpconn, err := net.Dial("tcp", addr) if err != nil { @@ -116,7 +121,7 @@ func FetchKeysDirect(serverName, addr, sni string) (*ServerKeys, *tls.Connection connectionState := tlsconn.ConnectionState() // 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) if err != nil { 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. // 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.MatchingServerName = serverName == keys.ServerName @@ -222,7 +227,7 @@ func checkVerifyKeys(keys ServerKeys, checks *KeyChecks) map[KeyID]Base64String ValidEd25519: len(publicKey) == 32, } 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 } checks.Ed25519Checks[keyID] = entry diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/request.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/request.go index 08219a71..01fec1bc 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/request.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/request.go @@ -20,12 +20,12 @@ type FederationRequest struct { // fields implement the JSON format needed for signing // specified in https://matrix.org/docs/spec/server_server/unstable.html#request-authentication fields struct { - Content rawJSON `json:"content,omitempty"` - Destination string `json:"destination"` - Method string `json:"method"` - Origin string `json:"origin"` - RequestURI string `json:"uri"` - Signatures map[string]map[string]string `json:"signatures,omitempty"` + Content rawJSON `json:"content,omitempty"` + Destination ServerName `json:"destination"` + Method string `json:"method"` + Origin ServerName `json:"origin"` + RequestURI string `json:"uri"` + 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 request path must begin with a slash. // 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 r.fields.Destination = destination r.fields.Method = strings.ToUpper(method) @@ -70,7 +70,7 @@ func (r *FederationRequest) Content() []byte { } // Origin returns the server that the request originated on. -func (r *FederationRequest) Origin() string { +func (r *FederationRequest) Origin() ServerName { 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 // Updates the request with the signature in place. // 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 { 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 { return err } - signedData, err := SignJSON(serverName, keyID, privateKey, data) + signedData, err := SignJSON(string(serverName), keyID, privateKey, data) if err != nil { 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. // We don't need to check the signature since we already know that it is // 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") } - if !isSafeInHTTPQuotedString(keyID) { + if !isSafeInHTTPQuotedString(string(keyID)) { return nil, fmt.Errorf("gomatrixserverlib: Request key ID isn't safe to include in an HTTP header") } 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 // HTTP and the headers aren't protected by the signature. 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) { request, err := readHTTPRequest(req) if err != nil { @@ -268,7 +268,7 @@ func readHTTPRequest(req *http.Request) (*FederationRequest, error) { } result.fields.Origin = origin 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 { result.fields.Signatures[origin][key] = sig } @@ -277,7 +277,7 @@ func readHTTPRequest(req *http.Request) (*FederationRequest, error) { 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) scheme = parts[0] if scheme != "X-Matrix" { @@ -294,10 +294,10 @@ func parseAuthorization(header string) (scheme, origin, key, sig string) { name := pair[0] value := strings.Trim(pair[1], "\"") if name == "origin" { - origin = value + origin = ServerName(value) } if name == "key" { - key = value + key = KeyID(value) } if name == "sig" { sig = value diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/resolve.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/resolve.go index d3090787..c3e1ff9e 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/resolve.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/resolve.go @@ -38,15 +38,15 @@ type DNSResult struct { } // LookupServer looks up a matrix server in DNS. -func LookupServer(serverName string) (*DNSResult, error) { +func LookupServer(serverName ServerName) (*DNSResult, error) { var result DNSResult result.Hosts = map[string]HostResult{} 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. 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 if err != nil { @@ -57,8 +57,8 @@ func LookupServer(serverName string) (*DNSResult, error) { return nil, err } // If there isn't a SRV record in DNS then fallback to "serverName:8448". - hosts[serverName] = []net.SRV{net.SRV{ - Target: serverName, + hosts[string(serverName)] = []net.SRV{net.SRV{ + Target: string(serverName), Port: 8448, }} } @@ -71,7 +71,7 @@ func LookupServer(serverName string) (*DNSResult, error) { } else { // There is a explicit port set in the server name. // 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 { return nil, err }