WIP: Migrating to web based command protocol

This commit is contained in:
Farhan Khan 2022-01-11 00:44:01 -05:00
parent c120357259
commit 9b44f7728a
4 changed files with 257 additions and 95 deletions

View File

@ -1,13 +1,14 @@
package main package main
import ( import (
"encoding/binary" "bytes"
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"io" "log"
"net" "net/http"
"os" "os"
"time"
"gitlab.com/khanzf/fedilogue/shared" "gitlab.com/khanzf/fedilogue/shared"
) )
@ -25,7 +26,7 @@ func main() {
/* Condition verification */ /* Condition verification */
totalflags := 0 totalflags := 0
var commandMap shared.CommandMap var commandMap shared.CommandMap
var responseback shared.ResponseBack //var responseback shared.ResponseBack
if *shutdownPtr { if *shutdownPtr {
totalflags++ totalflags++
@ -68,79 +69,96 @@ func main() {
fmt.Println(err) fmt.Println(err)
return return
} }
payload := bytes.NewReader(commandByte)
c, err := net.Dial("tcp", "127.0.0.1:5555") req, err := http.NewRequest("POST", "http://127.0.0.1:5555/"+commandMap.Type, payload)
if err != nil { if err != nil {
fmt.Println(err) log.Fatal("Error condition")
return
}
sizebytes := make([]byte, 4)
b := len(commandByte)
// Send the request
binary.LittleEndian.PutUint32(sizebytes, uint32(b))
_, err = c.Write(sizebytes)
if err != nil {
fmt.Println(err)
return
}
_, err = c.Write(commandByte)
if err != nil {
fmt.Println(err)
return
} }
// Read the response client := &http.Client{Timeout: 10 * time.Second}
n, err := io.ReadFull(c, sizebytes) _, err = client.Do(req)
if err != nil || n != 4 { //res, err := client.Do(req)
fmt.Println("err", err, n)
}
jsonsize := int(binary.LittleEndian.Uint32(sizebytes))
responsebytes := make([]byte, jsonsize)
_, err = io.ReadFull(c, responsebytes)
if err != nil { if err != nil {
fmt.Println("Read Error", err) log.Fatal(err)
}
err = json.Unmarshal(responsebytes, &responseback)
if err != nil {
fmt.Println("Unmarshal error", err)
} }
switch commandMap.Type { //resp, err := client.Do(req)
case "add":
fmt.Println(responseback.Message) /*
case "status": c, err := net.Dial("tcp", "127.0.0.1:5555")
fmt.Println("Status\t\tLastRun\t\t\tCaptureType\tEndpoint") if err != nil {
for endpoint, runninginstance := range responseback.RunningInstances { fmt.Println(err)
if runninginstance.Status == 0 { return
fmt.Fprintf(os.Stdout, "New\t")
fmt.Fprintf(os.Stdout, "\tNever\t\t\t")
} else if runninginstance.Status == 200 {
fmt.Fprintf(os.Stdout, "Running\t")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 429 {
fmt.Fprintf(os.Stdout, "TooManyRequests\t")
fmt.Fprintf(os.Stdout, "%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 600 {
fmt.Fprintf(os.Stdout, "ClientIssue")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 602 {
fmt.Fprintf(os.Stdout, "BadInstance")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 605 {
fmt.Fprintf(os.Stdout, "UnsupportedNode")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else {
fmt.Fprintf(os.Stdout, "%d\t", runninginstance.Status)
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
}
if runninginstance.LastRun == "Queued" {
fmt.Fprintf(os.Stdout, "\t\t")
}
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.CaptureType)
fmt.Fprintf(os.Stdout, "%s\n", endpoint)
} }
case "follow": sizebytes := make([]byte, 4)
fmt.Println("This is a follow test") b := len(commandByte)
}
// Send the request
binary.LittleEndian.PutUint32(sizebytes, uint32(b))
_, err = c.Write(sizebytes)
if err != nil {
fmt.Println(err)
return
}
_, err = c.Write(commandByte)
if err != nil {
fmt.Println(err)
return
}
// Read the response
n, err := io.ReadFull(c, sizebytes)
if err != nil || n != 4 {
fmt.Println("err", err, n)
}
jsonsize := int(binary.LittleEndian.Uint32(sizebytes))
responsebytes := make([]byte, jsonsize)
_, err = io.ReadFull(c, responsebytes)
if err != nil {
fmt.Println("Read Error", err)
}
err = json.Unmarshal(responsebytes, &responseback)
if err != nil {
fmt.Println("Unmarshal error", err)
}
switch commandMap.Type {
case "add":
fmt.Println(responseback.Message)
case "status":
fmt.Println("Status\t\tLastRun\t\t\tCaptureType\tEndpoint")
for endpoint, runninginstance := range responseback.RunningInstances {
if runninginstance.Status == 0 {
fmt.Fprintf(os.Stdout, "New\t")
fmt.Fprintf(os.Stdout, "\tNever\t\t\t")
} else if runninginstance.Status == 200 {
fmt.Fprintf(os.Stdout, "Running\t")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 429 {
fmt.Fprintf(os.Stdout, "TooManyRequests\t")
fmt.Fprintf(os.Stdout, "%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 600 {
fmt.Fprintf(os.Stdout, "ClientIssue")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 602 {
fmt.Fprintf(os.Stdout, "BadInstance")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else if runninginstance.Status == 605 {
fmt.Fprintf(os.Stdout, "UnsupportedNode")
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
} else {
fmt.Fprintf(os.Stdout, "%d\t", runninginstance.Status)
fmt.Fprintf(os.Stdout, "\t%s\t", runninginstance.LastRun)
}
if runninginstance.LastRun == "Queued" {
fmt.Fprintf(os.Stdout, "\t\t")
}
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")
}
*/
} }

View File

@ -1,41 +1,42 @@
package main package main
import ( import (
"encoding/binary"
"encoding/json" "encoding/json"
"io" "fmt"
"net" "io/ioutil"
"log"
"net/http"
"gitlab.com/khanzf/fedilogue/shared" "gitlab.com/khanzf/fedilogue/shared"
) )
func startctl() { func cmdFollow(w http.ResponseWriter, r *http.Request) {
logInfo("Starting ctl listener on 127.0.0.1:5555") body, err := ioutil.ReadAll(r.Body)
l, err := net.Listen("tcp", "127.0.0.1:5555")
if err != nil { if err != nil {
logFatal.Fatal("Unable to start listener:", err) fmt.Println(err)
return
} }
defer l.Close() defer r.Body.Close()
commandClient := make(chan net.Conn) var commandmap shared.CommandMap
err = json.Unmarshal(body, &commandmap)
go func(l net.Listener) { if err != nil {
for { logWarn("Unable to unmarshal here, exiting...")
c, err := l.Accept() return
if err != nil {
logFatal.Fatal("Error on accept", err)
}
commandClient <- c
}
}(l)
for {
c := <-commandClient // New client connection
go handleClient(c)
} }
go followInbox(commandmap.Endpoint)
fmt.Fprintf(w, "{}")
}
func startctl() {
http.HandleFunc("/follow", cmdFollow)
log.Print("Starting HTTP inbox on port 127.0.0.1:5555")
log.Fatal(http.ListenAndServe("127.0.0.1:5555", nil))
} }
/*
func handleClient(commandClient net.Conn) { func handleClient(commandClient net.Conn) {
defer commandClient.Close() defer commandClient.Close()
sizebyte := make([]byte, 4) sizebyte := make([]byte, 4)
@ -124,3 +125,4 @@ func handleClient(commandClient net.Conn) {
logFatal.Fatal("Error on write:", err) logFatal.Fatal("Error on write:", err)
} }
} }
*/

142
fedilogue/follow.go Normal file
View File

@ -0,0 +1,142 @@
package main
import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
"time"
"github.com/go-fed/httpsig"
)
func followInbox(inboxurl string) {
matchset := re.FindStringSubmatch(inboxurl)
if matchset == nil {
log.Fatal("Unable to regex")
}
inboxhostname := matchset[1]
fmt.Println("The hostname is", inboxhostname)
keyBytes, err := ioutil.ReadFile("keys/private.pem")
if err != nil {
log.Fatal(err)
}
pemBlock, _ := pem.Decode(keyBytes)
if pemBlock == nil {
log.Fatal("Invalid PEM format")
}
privateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
jsonRequest := fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://%[2]s/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://%[2]s/relay","cc":[],"id":"https://%[2]s/activities/bd0614f5-371d-4bd2-88b3-1ee12f7bf42a","object":"%[1]s","state":"pending","to":["%[1]s"],"type":"Follow"}`, inboxurl, settings.Hostname)
//var jsonBytes []byte
jsonBytes := []byte(jsonRequest)
payload := bytes.NewReader(jsonBytes)
prefs := []httpsig.Algorithm{httpsig.RSA_SHA256}
digestAlgorithm := httpsig.DigestSha256
headers := []string{httpsig.RequestTarget, "date", "host"}
signer, _, err := httpsig.NewSigner(prefs, digestAlgorithm, headers, httpsig.Signature, 0)
if err != nil {
log.Fatal(err.Error())
}
req, err := http.NewRequest("POST", inboxurl, payload)
if err != nil {
log.Fatal(err.Error())
}
if payload != nil {
req.Header.Add("content-type", "application/json")
}
req.Header.Add("date", time.Now().UTC().Format(http.TimeFormat))
req.Header.Add("host", inboxhostname)
keyID := "https://" + settings.Hostname + "/relay"
err = signer.SignRequest(privateKey, keyID, req, jsonBytes)
if err != nil {
log.Fatal(err.Error())
}
req.Header["Signature"][0] = strings.Replace(req.Header["Signature"][0], "algorithm=\"hs2019\"", "algorithm=\"rsa-sha256\"", 1)
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Timeout: 10 * time.Second, Transport: customTransport}
// client := &http.Client{Timeout: 10 * time.Second}
res, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Printf("Body : %s", body)
/*
matchset := re.FindStringSubmatch(targetInbox)
if matchset == nil {
return
}
inboxHost := matchset[1]
keyBytes, err := ioutil.ReadFile("keys/private.pem")
if err != nil {
log.Fatal(err)
}
pemBlock, _ := pem.Decode(keyBytes)
if pemBlock == nil {
log.Fatal("Invalid PEM format")
}
privateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
if err != nil {
log.Fatal(err)
}
//var jsonBytes []byte
jsonRequest := "{}"
jsonBytes := []byte(jsonRequest)
payload := bytes.NewReader(jsonBytes)
prefs := []httpsig.Algorithm{httpsig.RSA_SHA256}
digestAlgorithm := httpsig.DigestSha256
headers := []string{httpsig.RequestTarget, "date", "host"}
signer, _, err := httpsig.NewSigner(prefs, digestAlgorithm, headers, httpsig.Signature, 0)
if err != nil {
log.Fatal(err.Error())
}
req, err := http.NewRequest("POST", targetInbox, payload)
if err != nil {
log.Fatal(err.Error())
}
if payload != nil {
req.Header.Add("content-type", "application/json")
}
req.Header.Add("date", time.Now().UTC().Format(http.TimeFormat))
req.Header.Add("host", inboxHost)
keyID := "https://" + settings.Hostname + "/relay#mainkey"
err = signer.SignRequest(privateKey, keyID, req, jsonBytes)
if err != nil {
log.Fatal(err.Error())
}
fmt.Println(req)
*/
}

View File

@ -192,7 +192,7 @@ func internalFetch(w http.ResponseWriter, r *http.Request) {
func relay(w http.ResponseWriter, r *http.Request) { func relay(w http.ResponseWriter, r *http.Request) {
fmt.Println("Requesting: ", r.Host, " /relay") fmt.Println("Someone out there requested /relay")
publicKeyBytes, err := ioutil.ReadFile("keys/public.pem") publicKeyBytes, err := ioutil.ReadFile("keys/public.pem")
publicKeyString := string(publicKeyBytes) publicKeyString := string(publicKeyBytes)