diff options
-rw-r--r-- | main.go | 50 | ||||
-rw-r--r-- | outboxPost.go | 14 | ||||
-rw-r--r-- | verification.go | 29 |
3 files changed, 63 insertions, 30 deletions
@@ -22,7 +22,8 @@ import "github.com/gofrs/uuid" var Port = ":" + GetConfigValue("instanceport") var TP = GetConfigValue("instancetp") -var Domain = TP + "" + GetConfigValue("instance") +var Instance = GetConfigValue("instance") +var Domain = TP + "" + Instance var authReq = []string{"captcha","email","passphrase"} @@ -357,12 +358,13 @@ func main() { we.Close() - req, err := http.NewRequest("POST", r.FormValue("sendTo"), &b) + sendTo := r.FormValue("sendTo") + req, err := http.NewRequest("POST", sendTo, &b) CheckError(err, "error with post form req") - + req.Header.Set("Content-Type", we.FormDataContentType()) - req.Header.Set("Authorization", "Basic " + *Key) + req.Header.Set("Authorization", "Basic " + *Key) resp, err := http.DefaultClient.Do(req) @@ -1302,11 +1304,12 @@ func AddFollowersToActivity(db *sql.DB, activity Activity) Activity{ func CreateActivity(activityType string, obj ObjectBase) Activity { var newActivity Activity - + actor := FingerActor(obj.Actor.Id) + newActivity.AtContext.Context = "https://www.w3.org/ns/activitystreams" newActivity.Type = activityType newActivity.Published = obj.Published - newActivity.Actor = obj.Actor + newActivity.Actor = &actor newActivity.Object = &obj for _, e := range obj.To { @@ -1802,21 +1805,36 @@ func MakeActivityRequest(db *sql.DB, activity Activity) { auth = CreateTripCode(auth) for _, e := range activity.To { + if e != activity.Actor.Id { + + actor := FingerActor(e) - actor := GetActor(e) + _, instance := GetActorInstance(actor.Id) - if actor.Inbox != "" { - req, err := http.NewRequest("POST", actor.Inbox, bytes.NewBuffer(j)) - - req.Header.Set("Content-Type", activitystreams) - - req.Header.Set("Authorization", "Basic " + auth) + if actor.Inbox != "" { + req, err := http.NewRequest("POST", actor.Inbox, bytes.NewBuffer(j)) + + date := time.Now().UTC().Format(time.RFC1123) + path := strings.Replace(actor.Inbox, instance, "", 1) + + re := regexp.MustCompile("https?://(www.)?") + path = re.ReplaceAllString(path, "") - CheckError(err, "error with sending activity req to") + sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", "post", path, Instance, date) + encSig := ActivitySign(db, *activity.Actor, sig) + + req.Header.Set("Content-Type", activitystreams) + req.Header.Set("Date", date) + req.Header.Set("Signature", encSig) + req.Header.Set("Host", Instance) + req.Host = Instance - _, err = http.DefaultClient.Do(req) + CheckError(err, "error with sending activity req to") + + _, err = http.DefaultClient.Do(req) - CheckError(err, "error with sending activity resp to") + CheckError(err, "error with sending activity resp to") + } } } } diff --git a/outboxPost.go b/outboxPost.go index 8bddf42..5729b2d 100644 --- a/outboxPost.go +++ b/outboxPost.go @@ -530,25 +530,13 @@ func CheckCaptcha(db *sql.DB, captcha string) bool { func ParseInboxRequest(w http.ResponseWriter, r *http.Request, db *sql.DB) { activity := GetActivityFromJson(r, db) - - header := r.Header.Get("Authorization") - auth := strings.Split(header, " ") - - if len(auth) < 2 { + if !VerifyHeaderSignature(r, *activity.Actor) { response := RejectActivity(activity) MakeActivityRequest(db, response) return } - if !RemoteActorHasAuth(activity.Actor.Id, auth[1]) { - if !RemoteActorHasAuth(Domain, auth[1]) { - response := RejectActivity(activity) - MakeActivityRequest(db, response) - return - } - } - switch(activity.Type) { case "Create": for _, e := range activity.To { diff --git a/verification.go b/verification.go index 8c6cf98..e193746 100644 --- a/verification.go +++ b/verification.go @@ -17,6 +17,7 @@ import "encoding/base64" import crand "crypto/rand" import "io/ioutil" import "strings" +import "net/http" type Verify struct { Type string @@ -578,10 +579,14 @@ func ActivitySign(db *sql.DB, actor Actor, signature string) string { return "" } -func ActivityVerify(db *sql.DB, actor Actor, signature string, verify string) error { +func ActivityVerify(actor Actor, signature string, verify string) error { sig, _ := base64.StdEncoding.DecodeString(signature) + if actor.PublicKey.PublicKeyPem == "" { + actor = FingerActor(actor.Id) + } + block, _ := pem.Decode([]byte(actor.PublicKey.PublicKeyPem)) pub, _ := x509.ParsePKIXPublicKey(block.Bytes) @@ -590,3 +595,25 @@ func ActivityVerify(db *sql.DB, actor Actor, signature string, verify string) er return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA256, hashed.Sum(nil), sig) } + +func VerifyHeaderSignature(r *http.Request, actor Actor) bool { + method := strings.ToLower(r.Method) + path := r.URL.Path + host := r.Host + date := r.Header.Get("Date") + encSig := r.Header.Get("Signature") + + sig := fmt.Sprintf("(request-target): %s %s\\nhost: %s\\ndate: %s", method, path, host, date) + + t, _ := time.Parse(time.RFC1123, date) + + if(time.Now().Sub(t).Seconds() > 30) { + return false + } + + if ActivityVerify(actor, sig, encSig) != nil { + return false + } + + return true +} |