diff --git a/client/client.go b/client/client.go index c441b96..daede0e 100644 --- a/client/client.go +++ b/client/client.go @@ -1,12 +1,14 @@ package client import ( + "bytes" "crypto" "crypto/ecdsa" "crypto/ed25519" "crypto/rsa" "fmt" "net/http" + "net/url" "reflect" "github.com/common-fate/httpsig" @@ -14,9 +16,42 @@ import ( "github.com/common-fate/httpsig/alg_ed25519" "github.com/common-fate/httpsig/alg_rsa" "github.com/common-fate/httpsig/signer" + "github.com/opencontainers/go-digest" ) -func GetSigningClient(key crypto.PrivateKey, keyId string) (*http.Client, error) { +func Post(baseUrl *url.URL, key crypto.PrivateKey, keyId string, data []byte, simulateCaddy bool) (*http.Response, error) { + client, err := getSigningClient(key, keyId) + + if err != nil { + return nil, err + } + + id := digest.FromBytes(data) + + authUrl := baseUrl.JoinPath("auth") + + var req *http.Request + + req, err = http.NewRequest("POST", authUrl.String(), bytes.NewBuffer(data)) + + if err != nil { + return nil, err + } + + req.Header.Add("Content-Digest", string(id.Algorithm())+"="+id.Encoded()) + req.Header.Add("Content-Type", "application/json") + + if simulateCaddy { + req.Header.Add("X-Forwarded-Method", req.Method) + req.Header.Add("X-Forwarded-Uri", req.RequestURI) + } + + resp, err := client.Do(req) + + return resp, err +} + +func getSigningClient(key crypto.PrivateKey, keyId string) (*http.Client, error) { var alg signer.Algorithm switch p := key.(type) { diff --git a/client/register.go b/client/register.go index 7e7de84..a85669e 100644 --- a/client/register.go +++ b/client/register.go @@ -6,11 +6,12 @@ import ( "fmt" "io" "net/http" + "net/url" "crispbyte.dev/sig-auth/server" ) -func RegisterKey(key string, userId string) error { +func RegisterKey(baseUrl *url.URL, key string, userId string) error { request := server.RegisterRequest{ UserId: userId, Key: key, @@ -18,8 +19,10 @@ func RegisterKey(key string, userId string) error { json_data, _ := json.Marshal(request) + registerUrl := baseUrl.JoinPath("register") + resp, err := http.DefaultClient.Post( - "http://localhost:8080/register", + registerUrl.String(), "application/json", bytes.NewBuffer(json_data)) diff --git a/main.go b/main.go index dba520a..e459015 100644 --- a/main.go +++ b/main.go @@ -1,20 +1,18 @@ package main import ( - "bytes" "crypto" "encoding/json" "flag" "fmt" "io" "log" - "net/http" + "net/url" "os" "crispbyte.dev/sig-auth/client" "crispbyte.dev/sig-auth/keydirectory" "crispbyte.dev/sig-auth/server" - "github.com/opencontainers/go-digest" "golang.org/x/crypto/ssh" ) @@ -29,6 +27,8 @@ func main() { keyPath := flag.String("key", "", "Path to the private key (client mode) or public key (registration mode) to use") + baseUrlString := flag.String("base-url", "http://localhost:8080", "Base URL of the server") + simulateCaddy := flag.Bool("caddy", false, "Simulate caddy reverse proxy") useTempDb := flag.Bool("temp-db", false, "Use a temporary in-memory database") @@ -37,20 +37,27 @@ func main() { flag.Parse() + baseUrl, err := url.Parse(*baseUrlString) + + if err != nil { + flag.PrintDefaults() + return + } + if *useClient { if *keyPath == "" || *keyId == "" { flag.PrintDefaults() return } - runClient(*keyPath, *keyId, *simulateCaddy) + runClient(baseUrl, *keyPath, *keyId, *simulateCaddy) } else if *register { if *keyPath == "" || *user == "" { flag.PrintDefaults() return } - registerKey(*keyPath, *user) + registerKey(baseUrl, *keyPath, *user) } else { if !*useTempDb && *dbPath == "" { flag.PrintDefaults() @@ -61,7 +68,7 @@ func main() { } } -func runClient(keyFile string, keyId string, simulateCaddy bool) { +func runClient(baseUrl *url.URL, keyFile string, keyId string, simulateCaddy bool) { testData := map[string]string{"hello": "world"} json_data, _ := json.Marshal(testData) @@ -71,31 +78,7 @@ func runClient(keyFile string, keyId string, simulateCaddy bool) { log.Fatal(err) } - client, err := client.GetSigningClient(key, keyId) - - if err != nil { - log.Fatal(err) - } - - id := digest.FromBytes(json_data) - - var req *http.Request - - req, err = http.NewRequest("POST", "http://localhost:8080/post", bytes.NewBuffer(json_data)) - - if err != nil { - log.Fatal(err) - } - - req.Header.Add("Content-Digest", string(id.Algorithm())+"="+id.Encoded()) - req.Header.Add("Content-Type", "application/json") - - if simulateCaddy { - req.Header.Add("X-Forwarded-Method", req.Method) - req.Header.Add("X-Forwarded-Uri", req.RequestURI) - } - - resp, err := client.Do(req) + resp, err := client.Post(baseUrl, key, keyId, json_data, simulateCaddy) if err != nil { log.Fatal(err) @@ -141,7 +124,7 @@ func loadPrivateKey(keyFile string) (crypto.PrivateKey, error) { return ssh.ParseRawPrivateKey(keyBytes) } -func registerKey(keyFile string, userId string) { +func registerKey(baseUrl *url.URL, keyFile string, userId string) { keyBytes, err := os.ReadFile(keyFile) if err != nil { @@ -150,7 +133,7 @@ func registerKey(keyFile string, userId string) { keyText := string(keyBytes) - err = client.RegisterKey(keyText, userId) + err = client.RegisterKey(baseUrl, keyText, userId) if err != nil { log.Fatal(err) diff --git a/server/server.go b/server/server.go index cbd367a..b7eb74a 100644 --- a/server/server.go +++ b/server/server.go @@ -42,7 +42,7 @@ func Start(isCaddyAuth bool, keyDir keydirectory.RegistrationDirectory) error { handler = verifyHandler } - mux.Handle("/", handler) + mux.Handle("/auth", handler) mux.Handle("/register", getRegistrationHandler(keyDir)) err := http.ListenAndServe("localhost:8080", mux)