From 0f5e4d46ce33dac8e26d208bd747038565479865 Mon Sep 17 00:00:00 2001 From: Naoki Kosaka Date: Sun, 10 May 2020 13:59:15 +0900 Subject: [PATCH] Fix Retrieve Actor. --- decode.go | 17 +++++-- decode_test.go | 133 ++++++++++++++++++++++++------------------------- 2 files changed, 76 insertions(+), 74 deletions(-) diff --git a/decode.go b/decode.go index 54475db..9fdc702 100644 --- a/decode.go +++ b/decode.go @@ -9,10 +9,10 @@ import ( "net/http" "strconv" + "github.com/go-fed/httpsig" "github.com/spf13/viper" activitypub "github.com/yukimochi/Activity-Relay/ActivityPub" keyloader "github.com/yukimochi/Activity-Relay/KeyLoader" - "github.com/yukimochi/httpsig" ) func decodeActivity(request *http.Request) (*activitypub.Activity, *activitypub.Actor, []byte, error) { @@ -27,12 +27,12 @@ func decodeActivity(request *http.Request) (*activitypub.Activity, *activitypub. return nil, nil, nil, err } KeyID := verifier.KeyId() - remoteActor := new(activitypub.Actor) - err = remoteActor.RetrieveRemoteActor(KeyID, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", viper.GetString("relay_servicename"), version, hostURL.Host), actorCache) + keyOwnerActor := new(activitypub.Actor) + err = keyOwnerActor.RetrieveRemoteActor(KeyID, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", viper.GetString("relay_servicename"), version, hostURL.Host), actorCache) if err != nil { return nil, nil, nil, err } - PubKey, err := keyloader.ReadPublicKeyRSAfromString(remoteActor.PublicKey.PublicKeyPem) + PubKey, err := keyloader.ReadPublicKeyRSAfromString(keyOwnerActor.PublicKey.PublicKeyPem) if PubKey == nil { return nil, nil, nil, errors.New("Failed parse PublicKey from string") } @@ -55,11 +55,18 @@ func decodeActivity(request *http.Request) (*activitypub.Activity, *activitypub. return nil, nil, nil, errors.New("Digest header is mismatch") } + // Parse Activity var activity activitypub.Activity err = json.Unmarshal(body, &activity) if err != nil { return nil, nil, nil, err } - return &activity, remoteActor, body, nil + var remoteActor activitypub.Actor + err = remoteActor.RetrieveRemoteActor(activity.Actor, fmt.Sprintf("%s (golang net/http; Activity-Relay %s; %s)", viper.GetString("relay_servicename"), version, hostURL.Host), actorCache) + if err != nil { + return nil, nil, nil, err + } + + return &activity, &remoteActor, body, nil } diff --git a/decode_test.go b/decode_test.go index 29bc8bb..71571c6 100644 --- a/decode_test.go +++ b/decode_test.go @@ -2,38 +2,17 @@ package main import ( "bytes" + "fmt" "io/ioutil" "net/http" - "net/http/httptest" "os" + "strconv" "testing" state "github.com/yukimochi/Activity-Relay/State" ) -func TestHandleInboxNoSignure(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handleInbox(w, r, decodeActivity) - })) - defer s.Close() - - req, _ := http.NewRequest("POST", s.URL, nil) - client := new(http.Client) - r, err := client.Do(req) - if err != nil { - t.Fatalf("Failed - " + err.Error()) - } - if r.StatusCode != 400 { - t.Fatalf("Failed - StatusCode is not 400") - } -} - -func TestHandleInboxWithRemoteActor(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handleInbox(w, r, decodeActivity) - })) - defer s.Close() - +func TestDecodeActivity(t *testing.T) { relayState.AddSubscription(state.Subscription{ Domain: "innocent.yukimochi.io", InboxURL: "https://innocent.yukimochi.io/inbox", @@ -41,30 +20,29 @@ func TestHandleInboxWithRemoteActor(t *testing.T) { file, _ := os.Open("./misc/create.json") body, _ := ioutil.ReadAll(file) - req, _ := http.NewRequest("POST", s.URL+"/inbox", bytes.NewReader(body)) + length := strconv.Itoa(len(body)) + req, _ := http.NewRequest("POST", "/inbox", bytes.NewReader(body)) req.Host = "relay.01.cloudgarage.yukimochi.io" - req.Header.Set("date", "Sun, 23 Dec 2018 07:39:37 GMT") - req.Header.Set("digest", "SHA-256=mxgIzbPwBuNYxmjhQeH0vWeEedQGqR1R7zMwR/XTfX8=") - req.Header.Set("content-type", "application/activity+json") - req.Header.Set("signature", `keyId="https://innocent.yukimochi.io/users/YUKIMOCHI#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) - client := new(http.Client) - r, err := client.Do(req) + req.Header.Add("content-length", length) + req.Header.Add("content-type", "application/activity+json") + req.Header.Add("date", "Sun, 23 Dec 2018 07:39:37 GMT") + req.Header.Add("digest", "SHA-256=mxgIzbPwBuNYxmjhQeH0vWeEedQGqR1R7zMwR/XTfX8=") + req.Header.Add("signature", `keyId="https://innocent.yukimochi.io/users/YUKIMOCHI#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) + + activity, actor, _, err := decodeActivity(req) if err != nil { t.Fatalf("Failed - " + err.Error()) } - if r.StatusCode != 202 { - t.Fatalf("Failed - StatusCode is not 202") + + if activity.Actor != actor.ID { + fmt.Println(actor.ID) + t.Fatalf("Failed - retrieved actor is invalid") } relayState.DelSubscription("innocent.yukimochi.io") } -func TestHandleInboxWithNotfoundRemoteActor(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handleInbox(w, r, decodeActivity) - })) - defer s.Close() - +func TestDecodeActivityWithNoSignature(t *testing.T) { relayState.AddSubscription(state.Subscription{ Domain: "innocent.yukimochi.io", InboxURL: "https://innocent.yukimochi.io/inbox", @@ -72,30 +50,23 @@ func TestHandleInboxWithNotfoundRemoteActor(t *testing.T) { file, _ := os.Open("./misc/create.json") body, _ := ioutil.ReadAll(file) - req, _ := http.NewRequest("POST", s.URL+"/inbox", bytes.NewReader(body)) + length := strconv.Itoa(len(body)) + req, _ := http.NewRequest("POST", "/inbox", bytes.NewReader(body)) req.Host = "relay.01.cloudgarage.yukimochi.io" - req.Header.Set("date", "Sun, 23 Dec 2018 07:39:37 GMT") - req.Header.Set("digest", "SHA-256=mxgIzbPwBuNYxmjhQeH0vWeEedQGqR1R7zMwR/XTfX8=") - req.Header.Set("content-type", "application/activity+json") - req.Header.Set("signature", `keyId="https://innocent.yukimochi.io/users/admin#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) - client := new(http.Client) - r, err := client.Do(req) - if err != nil { - t.Fatalf("Failed - " + err.Error()) - } - if r.StatusCode != 400 { - t.Fatalf("Failed - StatusCode is not 400") + req.Header.Add("content-length", length) + req.Header.Add("content-type", "application/activity+json") + req.Header.Add("date", "Sun, 23 Dec 2018 07:39:37 GMT") + req.Header.Add("digest", "SHA-256=mxgIzbPwBuNYxmjhQeH0vWeEedQGqR1R7zMwR/XTfX8=") + + _, _, _, err := decodeActivity(req) + if err.Error() != "neither \"Signature\" nor \"Authorization\" have signature parameters" { + t.Fatalf("Failed - Accept request without signature") } relayState.DelSubscription("innocent.yukimochi.io") } -func TestHandleInboxInvalidDigestWithRemoteActor(t *testing.T) { - s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - handleInbox(w, r, decodeActivity) - })) - defer s.Close() - +func TestDecodeActivityWithNotFoundKeyId(t *testing.T) { relayState.AddSubscription(state.Subscription{ Domain: "innocent.yukimochi.io", InboxURL: "https://innocent.yukimochi.io/inbox", @@ -103,19 +74,43 @@ func TestHandleInboxInvalidDigestWithRemoteActor(t *testing.T) { file, _ := os.Open("./misc/create.json") body, _ := ioutil.ReadAll(file) - req, _ := http.NewRequest("POST", s.URL+"/inbox", bytes.NewReader(body)) + length := strconv.Itoa(len(body)) + req, _ := http.NewRequest("POST", "/inbox", bytes.NewReader(body)) req.Host = "relay.01.cloudgarage.yukimochi.io" - req.Header.Set("date", "Sun, 23 Dec 2018 07:39:37 GMT") - req.Header.Set("digest", "SHA-256=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") - req.Header.Set("content-type", "application/activity+json") - req.Header.Set("signature", `keyId="https://innocent.yukimochi.io/users/YUKIMOCHI#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) - client := new(http.Client) - r, err := client.Do(req) - if err != nil { - t.Fatalf("Failed - " + err.Error()) - } - if r.StatusCode != 400 { - t.Fatalf("Failed - StatusCode is not 400") + req.Header.Add("content-length", length) + req.Header.Add("content-type", "application/activity+json") + req.Header.Add("date", "Sun, 23 Dec 2018 07:39:37 GMT") + req.Header.Add("digest", "SHA-256=mxgIzbPwBuNYxmjhQeH0vWeEedQGqR1R7zMwR/XTfX8=") + req.Header.Add("signature", `keyId="https://innocent.yukimochi.io/users/admin#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) + + _, _, _, err := decodeActivity(req) + if err.Error() != "404 Not Found" { + t.Fatalf("Failed - Accept notfound KeyId") + } + + relayState.DelSubscription("innocent.yukimochi.io") +} + +func TestDecodeActivityWithInvalidDigest(t *testing.T) { + relayState.AddSubscription(state.Subscription{ + Domain: "innocent.yukimochi.io", + InboxURL: "https://innocent.yukimochi.io/inbox", + }) + + file, _ := os.Open("./misc/create.json") + body, _ := ioutil.ReadAll(file) + length := strconv.Itoa(len(body)) + req, _ := http.NewRequest("POST", "/inbox", bytes.NewReader(body)) + req.Host = "relay.01.cloudgarage.yukimochi.io" + req.Header.Add("content-length", length) + req.Header.Add("content-type", "application/activity+json") + req.Header.Add("date", "Sun, 23 Dec 2018 07:39:37 GMT") + req.Header.Add("digest", "SHA-256=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") + req.Header.Add("signature", `keyId="https://innocent.yukimochi.io/users/YUKIMOCHI#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="MhxXhL21RVp8VmALER2U/oJlWldJAB2COiU2QmwGopLD2pw1c32gQvg0PaBRHfMBBOsidZuRRnj43Kn488zW2xV3n3DYWcGscSh527/hhRzcpLVX2kBqbf/WeQzJmfJVuOX4SzivVhnnUB8PvlPj5LRHpw4n/ctMTq37strKDl9iZg9rej1op1YFJagDxm3iPzAhnv8lzO4RI9dstt2i/sN5EfjXai97oS7EgI//Kj1wJCRk9Pw1iTsGfPTkbk/aVZwDt7QGGvGDdO0JJjsCqtIyjojoyD9hFY9GzMqvTwVIYJrh54AUHq2i80veybaOBbCFcEaK0RpKoLs101r5Uw=="`) + + _, _, _, err := decodeActivity(req) + if err.Error() != "crypto/rsa: verification error" { + t.Fatalf("Failed - Accept unvalid digest") } relayState.DelSubscription("innocent.yukimochi.io")