Check if httpsig keyID matches actor and attributedTo
parent
c8a8e1ec91
commit
5196dcd9a5
|
@ -7,6 +7,7 @@ package activitypub
|
|||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
|
@ -106,7 +107,25 @@ func PersonInbox(ctx *context.APIContext) {
|
|||
}
|
||||
|
||||
var activity ap.Activity
|
||||
activity.UnmarshalJSON(body)
|
||||
err = activity.UnmarshalJSON(body)
|
||||
if err != nil {
|
||||
ctx.ServerError("UnmarshalJSON", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Make sure keyID matches the user doing the activity
|
||||
_, keyID, _ := getKeyID(ctx.Req)
|
||||
if activity.Actor != nil && !strings.HasPrefix(keyID, activity.Actor.GetID().String()) {
|
||||
ctx.ServerError("Actor does not match HTTP signature keyID", nil)
|
||||
return
|
||||
}
|
||||
if activity.AttributedTo != nil && !strings.HasPrefix(keyID, activity.AttributedTo.GetID().String()) {
|
||||
ctx.ServerError("AttributedTo does not match HTTP signature keyID", nil)
|
||||
return
|
||||
}
|
||||
// TODO: Check activity.Object actor and attributedTo
|
||||
|
||||
// Process activity
|
||||
switch activity.Type {
|
||||
case ap.FollowType:
|
||||
activitypub.Follow(ctx, activity)
|
||||
|
@ -172,7 +191,7 @@ func PersonOutbox(ctx *context.APIContext) {
|
|||
|
||||
for _, star := range stars {
|
||||
object := ap.Note{Type: ap.NoteType, Content: ap.NaturalLanguageValuesNew()}
|
||||
object.Content.Set("en", ap.Content("Starred " + star.Name))
|
||||
object.Content.Set("en", ap.Content("Starred "+star.Name))
|
||||
create := ap.Create{Type: ap.CreateType, Object: object}
|
||||
outbox.OrderedItems.Append(create)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package activitypub
|
|||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/forgefed"
|
||||
"code.gitea.io/gitea/modules/activitypub"
|
||||
|
@ -102,12 +103,26 @@ func RepoInbox(ctx *context.APIContext) {
|
|||
return
|
||||
}
|
||||
|
||||
// Make sure keyID matches the user doing the activity
|
||||
_, keyID, _ := getKeyID(ctx.Req)
|
||||
actor, ok := activity["actor"]
|
||||
if ok && !strings.HasPrefix(keyID, actor.(string)) {
|
||||
ctx.ServerError("Actor does not match HTTP signature keyID", nil)
|
||||
return
|
||||
}
|
||||
attributedTo, ok := activity["attributedTo"]
|
||||
if ok && !strings.HasPrefix(keyID, attributedTo.(string)) {
|
||||
ctx.ServerError("AttributedTo does not match HTTP signature keyID", nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Process activity
|
||||
switch activity["type"].(ap.ActivityVocabularyType) {
|
||||
case ap.CreateType:
|
||||
// Create activity, extract the object
|
||||
object, ok := activity["object"].(map[string]interface{})
|
||||
if ok {
|
||||
ctx.ServerError("Activity does not contain object", err)
|
||||
ctx.ServerError("Create activity does not contain object", err)
|
||||
return
|
||||
}
|
||||
objectBinary, err := json.Marshal(object)
|
||||
|
|
|
@ -42,15 +42,22 @@ func getPublicKeyFromResponse(b []byte, keyID *url.URL) (p crypto.PublicKey, err
|
|||
return p, err
|
||||
}
|
||||
|
||||
func getKeyID(r *http.Request) (httpsig.Verifier, string, error) {
|
||||
v, err := httpsig.NewVerifier(r)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return v, v.KeyId(), nil
|
||||
}
|
||||
|
||||
func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, err error) {
|
||||
r := ctx.Req
|
||||
|
||||
// 1. Figure out what key we need to verify
|
||||
v, err := httpsig.NewVerifier(r)
|
||||
v, ID, err := getKeyID(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ID := v.KeyId()
|
||||
idIRI, err := url.Parse(ID)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -65,7 +72,6 @@ func verifyHTTPSignatures(ctx *gitea_context.APIContext) (authenticated bool, er
|
|||
return
|
||||
}
|
||||
// 3. Verify the other actor's key
|
||||
// TODO: Verify attributedTo matches keyID
|
||||
algo := httpsig.Algorithm(setting.Federation.Algorithms[0])
|
||||
authenticated = v.Verify(pubKey, algo) == nil
|
||||
return authenticated, err
|
||||
|
|
Loading…
Reference in New Issue