diff --git a/README.md b/README.md index 8bcb182..98b8605 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,14 @@ Fedilogue is configured by the `config.jsonc` file. Start by copying the `config `config.jsonc` and edit the file with your use-case values. The configuration file is written in jsonc and has enclosed explanations that should be self-explanatory. +### Generate private and public key +``` +cd fedilogue +mkdir -p keys +openssl genrsa -out keys/private.pem 3072 +openssl rsa -in keys/private.pem -pubout -out public-key.pem +``` + ## Contact Ping me at [@fikran@thebag.social](https://thebag.social/@fikran) diff --git a/fedictl/fedictl.go b/fedictl/fedictl.go index 149db6b..3e0465c 100644 --- a/fedictl/fedictl.go +++ b/fedictl/fedictl.go @@ -1,7 +1,6 @@ package main import ( - "gitlab.com/khanzf/fedilogue/shared" "encoding/binary" "encoding/json" "flag" @@ -9,6 +8,8 @@ import ( "io" "net" "os" + + "gitlab.com/khanzf/fedilogue/shared" ) func main() { @@ -18,6 +19,7 @@ func main() { resumePtr := flag.String("resume", "", "Instance to Resume") addPtr := flag.String("add", "", "Instance to add") statusPtr := flag.Bool("status", false, "Check status") + followPtr := flag.String("follow", "", "Follow a target relay") flag.Parse() /* Condition verification */ @@ -46,6 +48,13 @@ func main() { totalflags++ commandMap.Type = "resume" } + if *followPtr != "" { + totalflags++ + commandMap.Type = "follow" + commandMap.Endpoint = *followPtr + + } + if totalflags > 1 { fmt.Println("Incompatible arguments, exiting.") os.Exit(1) @@ -59,6 +68,7 @@ func main() { fmt.Println(err) return } + c, err := net.Dial("tcp", "127.0.0.1:5555") if err != nil { fmt.Println(err) @@ -130,5 +140,7 @@ func main() { fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType) fmt.Fprintf(os.Stdout, "%s\n", endpoint) } + case "follow": + fmt.Println("This is a follow test") } } diff --git a/fedilogue/config.go b/fedilogue/config.go index fb203df..78537c9 100644 --- a/fedilogue/config.go +++ b/fedilogue/config.go @@ -39,6 +39,7 @@ type Settings struct { Externalaccounts []ExtAccount `"json:externalaccounts"` MassFollowers []MassFollower `"json:massfollowers"` LogLevel int `"json:loglevel"` + Hostname string `"json:hostname"` } var settings Settings diff --git a/fedilogue/config.jsonc.sample b/fedilogue/config.jsonc.sample index 388a48c..4e39c1d 100644 --- a/fedilogue/config.jsonc.sample +++ b/fedilogue/config.jsonc.sample @@ -55,6 +55,8 @@ } ], + "hostname": "myhostname", + /* Log Level: * 0 = No logs diff --git a/fedilogue/ctl.go b/fedilogue/ctl.go index 68026cd..09c628c 100644 --- a/fedilogue/ctl.go +++ b/fedilogue/ctl.go @@ -82,6 +82,10 @@ func handleClient(commandClient net.Conn) { ri_mutex.Unlock() } //ri_mutex.Unlock() + case "follow": + logInfo("Follow handling...") + responseback.Message = "Trying to follow " + commandmap.Endpoint + go followInbox(commandmap.Endpoint) case "suspend": logFatal.Fatal("Suspend") case "resume": diff --git a/fedilogue/fedilogue.go b/fedilogue/fedilogue.go index b393427..18ef088 100644 --- a/fedilogue/fedilogue.go +++ b/fedilogue/fedilogue.go @@ -113,7 +113,7 @@ func main() { } go startctl() - //go webmain() + go webmain() runtime.Goexit() } diff --git a/fedilogue/web.go b/fedilogue/web.go index 03659d0..fb65e23 100644 --- a/fedilogue/web.go +++ b/fedilogue/web.go @@ -4,6 +4,7 @@ import ( // "crypto/sha1" "encoding/json" "fmt" + // "html" "io/ioutil" "log" @@ -23,6 +24,19 @@ type CreateObject struct { Type string `json:"type"` } +// CreateObject - Used by post web receiver +type AnnounceObject struct { + ID string `json:"id"` + Actor string `json:"actor"` + To []string `json:"to"` + Type string `json:"type"` + Object string `json:"object"` +} + +/* +{"@context": "https://www.w3.org/ns/activitystreams", "type": "Announce", "to": ["https://relay.101010.pl/followers"], "actor": "https://relay.101010.pl/actor", "object": "https://social.tchncs.de/users/keara/statuses/107594176486878867", "id": "https://relay.101010.pl/activities/7666bbe3-4448-4d99-919c-a618e0a912e9"} +*/ + // RelayBase - The base object used by web receiver type RelayBase struct { Actor string `json:"actor"` @@ -99,23 +113,27 @@ func webfinger(w http.ResponseWriter, r *http.Request) { func inboxHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + fmt.Println("Start of Inbox") + body, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Println(err) return } + defer r.Body.Close() var findtype RelayBase err = json.Unmarshal(body, &findtype) if err != nil { - log.Fatal("Unable to unmarshal here, exiting...") + logWarn("Unable to unmarshal here, exiting...") + return } switch findtype.Type { case "Create": var createobject CreateObject - err = json.Unmarshal(findtype.Object, &createobject) + err = json.Unmarshal(body, &createobject) if err != nil { return } @@ -123,20 +141,72 @@ func inboxHandler() http.HandlerFunc { go check_activity(createobject.ID) slashend := strings.Index(createobject.ID[8:], "/") newinstance := createobject.ID[8 : 8+slashend] - log.Print("The at sign is: ", newinstance) go CheckInstance(newinstance, "") + case "Update": + case "Reject": + case "Add": + case "Remove": case "Like": - case "Announcement": + case "Announce": + var announceobject AnnounceObject + err = json.Unmarshal(body, &announceobject) + if err != nil { + fmt.Println(err.Error()) + return + } + check_activity(announceobject.Object) + + matchset := re.FindStringSubmatch(announceobject.Object) + if matchset != nil { + newinstance := matchset[1] + go CheckInstance(newinstance, "") + } case "Delete": case "Undo": default: - fmt.Println("Others --> " + findtype.Type) + fmt.Println("Unknown Others --> " + findtype.Type) } + + w.Header().Set("Content-Type", "application/json") + fmt.Fprintf(w, "{}") + fmt.Println("End of Inbox") } } +func internalFetch(w http.ResponseWriter, r *http.Request) { + + publicKeyBytes, err := ioutil.ReadFile("keys/public.pem") + publicKeyString := string(publicKeyBytes) + publicKeyString = strings.Replace(publicKeyString, "\n", "\\n", -11) + if err != nil { + log.Fatal(err) + } + + staticjson := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[1]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"endpoints":{"oauthAuthorizationEndpoint":"https://%[1]s/oauth/authorize","oauthRegistrationEndpoint":"https://%[1]s/api/v1/apps","oauthTokenEndpoint":"https://%[1]s/oauth/token","sharedInbox":"https://%[1]s/inbox","uploadMedia":"https://%[1]s/api/ap/upload_media"},"followers":"https://%[1]s/internal/fetch/followers","following":"https://%[1]s/internal/fetch/following","id":"https://%[1]s/internal/fetch","inbox":"https://%[1]s/internal/fetch/inbox","invisible":true,"manuallyApprovesFollowers":false,"name":"Pleroma","preferredUsername":"fedilogue","publicKey":{"id":"https://%[1]s/internal/fetch#main-key","owner":"https://%[1]s/internal/fetch","publicKeyPem":"%[2]s"},"summary":"Fedilogue Key or something.","type":"Application","url":"https://%[1]s/internal/fetch"}`, r.Host, publicKeyString) + + fmt.Fprintf(w, staticjson) + +} + +func relay(w http.ResponseWriter, r *http.Request) { + + fmt.Println("Requesting: ", r.Host, " /relay") + + publicKeyBytes, err := ioutil.ReadFile("keys/public.pem") + publicKeyString := string(publicKeyBytes) + publicKeyString = strings.Replace(publicKeyString, "\n", "\\n", -11) + if err != nil { + log.Fatal(err) + } + + staticjson := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[1]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"alsoKnownAs":[],"attachment":[],"capabilities":{},"discoverable":false,"endpoints":{"oauthAuthorizationEndpoint":"https://%[1]s/oauth/authorize","oauthRegistrationEndpoint":"https://%[1]s/api/v1/apps","oauthTokenEndpoint":"https://%[1]s/oauth/token","sharedInbox":"https://%[1]s/inbox","uploadMedia":"https://%[1]s/api/ap/upload_media"},"featured":"https://%[1]s/relay/collections/featured","followers":"https://%[1]s/relay/followers","following":"https://%[1]s/relay/following","id":"https://%[1]s/relay","inbox":"https://%[1]s/relay/inbox","manuallyApprovesFollowers":false,"name":null,"outbox":"https://%[1]s/relay/outbox","preferredUsername":"relay","publicKey":{"id":"https://%[1]s/relay#main-key","owner":"https://%[1]s/relay","publicKeyPem":"%[2]s"},"summary":"","tag":[],"type":"Person","url":"https://%[1]s/relay"}`, r.Host, publicKeyString) + + fmt.Fprintf(w, staticjson) + +} + func usersFedilogueFollowers(w http.ResponseWriter, r *http.Request) { fmt.Println("PATH --> ", r.URL.Path) host := r.Host @@ -201,7 +271,7 @@ func usersFedilogue(w http.ResponseWriter, r *http.Request) { actorjsonmap["publicKey"] = publicKey actorjsonmap["summary"] = "" actorjsonmap["tag"] = tag - actorjsonmap["type"] = "Person" + actorjsonmap["type"] = "Application" actorjsonmap["uri"] = "https://" + host + "/users/fedilogue" actorjsonbin, err := json.Marshal(actorjsonmap) @@ -216,17 +286,32 @@ func usersFedilogue(w http.ResponseWriter, r *http.Request) { } func errorHandler(w http.ResponseWriter, r *http.Request) { - fmt.Println("404 --> ", r.URL.Path) + for name, headers := range r.Header { + fmt.Println("ROW: ", name, " ", headers) + for _, h := range headers { + fmt.Fprintf(w, "%v: %v\n", name, h) + } + } + + reqBody, err := ioutil.ReadAll(r.Body) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("POST DATA: %s\n", reqBody) + } func webmain() { http.HandleFunc("/.well-known/webfinger", webfinger) http.HandleFunc("/.well-known/host-meta", hostmeta) http.HandleFunc("/inbox", inboxHandler()) + http.HandleFunc("/internal/fetch", internalFetch) + http.HandleFunc("/relay", relay) http.HandleFunc("/users/fedilogue", usersFedilogue) http.HandleFunc("/users/fedilogue/followers", usersFedilogueFollowers) http.HandleFunc("/users/fedilogue/following", usersFedilogueFollowing) http.HandleFunc("/", errorHandler) - log.Print("Starting HTTP inbox on port 8080") - log.Fatal(http.ListenAndServe(":8080", nil)) + log.Print("Starting HTTP inbox on port 127.0.0.1:8042") + log.Fatal(http.ListenAndServe("127.0.0.1:8042", nil)) } diff --git a/go.mod b/go.mod index afebd5a..9015141 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gitlab.com/khanzf/fedilogue go 1.17 require ( + github.com/go-fed/httpsig v1.1.0 github.com/jackc/pgx/v4 v4.14.1 github.com/microcosm-cc/bluemonday v1.0.16 muzzammil.xyz/jsonc v0.0.0-20201229145248-615b0916ca38 @@ -21,5 +22,6 @@ require ( github.com/jackc/puddle v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect + golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect golang.org/x/text v0.3.6 // indirect ) diff --git a/go.sum b/go.sum index 39a7e3a..5a10a7a 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= +github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -155,8 +157,10 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=