From 62b51a6d0946035eaaf0b04d4e5de78dd3c2adca Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Sat, 3 Aug 2024 12:54:32 +0200 Subject: [PATCH] work in progress: * usage page now has more dynamic part where user can enter id and publis ssh keys and the server will generate the appropriate commmands to execute depending on the local and remote shell. --- cmd/converge/converge.go | 3 + cmd/converge/convergeaccess.go | 36 +++++++ cmd/converge/pagehandler.go | 27 +----- cmd/converge/usage.go | 24 +++++ cmd/templaterender/render.go | 11 ++- pkg/models/convergeaccess.go | 11 +++ pkg/server/templates/index.templ | 7 +- pkg/server/templates/usage.templ | 158 ++++++++++++++++++++++++++++--- 8 files changed, 237 insertions(+), 40 deletions(-) create mode 100644 cmd/converge/convergeaccess.go create mode 100644 cmd/converge/usage.go create mode 100644 pkg/models/convergeaccess.go diff --git a/cmd/converge/converge.go b/cmd/converge/converge.go index bae64aa..5c4edf4 100644 --- a/cmd/converge/converge.go +++ b/cmd/converge/converge.go @@ -161,6 +161,9 @@ func main() { http.FileServer(http.Dir(downloadDir)))) http.HandleFunc("/", catchAllHandler) + // create usage generator + http.HandleFunc("/usage", generateCLIExammple) + // Start HTTP server fmt.Println("Rendez-vous server listening on :8000") log.Fatal(http.ListenAndServe(":8000", nil)) diff --git a/cmd/converge/convergeaccess.go b/cmd/converge/convergeaccess.go new file mode 100644 index 0000000..f69407f --- /dev/null +++ b/cmd/converge/convergeaccess.go @@ -0,0 +1,36 @@ +package main + +import ( + "converge/pkg/models" + "converge/pkg/server/converge" + "net/http" + "strings" +) + +func getConvergeAccess(r *http.Request, sshRemoteUser string) models.ConvergeAccess { + secure := "" + if r.TLS == nil { + secure = "" + } else { + secure = "s" + } + for _, header := range []string{"X-Forwarded-Proto", "X-Scheme", "X-Forwarded-Scheme"} { + values := r.Header.Values(header) + for _, value := range values { + if strings.ToLower(value) == "https" { + secure = "s" + } + } + } + + location, err := converge.GetUserLocation(r) + if err != nil { + panic(err) + } + return models.ConvergeAccess{ + Secure: secure, + HostPort: r.Host, + Location: location, + Username: sshRemoteUser, + } +} diff --git a/cmd/converge/pagehandler.go b/cmd/converge/pagehandler.go index e0909cc..bdc256e 100644 --- a/cmd/converge/pagehandler.go +++ b/cmd/converge/pagehandler.go @@ -1,34 +1,14 @@ package main import ( - "converge/pkg/server/converge" templates2 "converge/pkg/server/templates" "net/http" "os" - "strings" ) func pageHandler(w http.ResponseWriter, r *http.Request) { - secure := "" - if r.TLS == nil { - secure = "" - } else { - secure = "s" - } - for _, header := range []string{"X-Forwarded-Proto", "X-Scheme", "X-Forwarded-Scheme"} { - values := r.Header.Values(header) - for _, value := range values { - if strings.ToLower(value) == "https" { - secure = "s" - } - } - } username, _ := os.LookupEnv("CONVERGE_USERNAME") - - location, err := converge.GetUserLocation(r) - if err != nil { - panic(err) - } + access := getConvergeAccess(r, username) switch r.URL.Path { case "": @@ -37,12 +17,13 @@ func pageHandler(w http.ResponseWriter, r *http.Request) { fallthrough case "index.html": templates2.AboutTab().Render(r.Context(), w) + // TODO use contexts later. case "usage.html": - templates2.UsageTab(secure, r.Host, username).Render(r.Context(), w) + templates2.UsageTab(access).Render(r.Context(), w) case "downloads.html": templates2.DownloadsTab().Render(r.Context(), w) case "sessions.html": - templates2.SessionsTab(nil, location).Render(r.Context(), w) + templates2.SessionsTab(nil, access.Location).Render(r.Context(), w) default: http.NotFound(w, r) } diff --git a/cmd/converge/usage.go b/cmd/converge/usage.go new file mode 100644 index 0000000..63304ff --- /dev/null +++ b/cmd/converge/usage.go @@ -0,0 +1,24 @@ +package main + +import ( + "log" + "net/http" + "time" +) + +func generateCLIExammple(w http.ResponseWriter, r *http.Request) { + log.Println("usage: got ", r.URL.Path) + + err := r.ParseForm() + if err != nil { + http.Error(w, "Error parsing form", http.StatusBadRequest) + return + } + remote_shells := r.Form["remote-shell"] + local_shells := r.Form["local-shhell"] + keys := r.FormValue("ssh-keys") + log.Printf("remote_shells %v", remote_shells) + log.Printf("local_shells %v", local_shells) + log.Printf("ssh-keys %v", keys) + w.Write([]byte(time.Now().Format(time.DateTime))) +} diff --git a/cmd/templaterender/render.go b/cmd/templaterender/render.go index 01bffee..3ea7024 100644 --- a/cmd/templaterender/render.go +++ b/cmd/templaterender/render.go @@ -37,11 +37,18 @@ func main() { panic(err) } + access := models.ConvergeAccess{ + Secure: "s", + HostPort: "example.com", + Location: netherlands, + Username: "converge", + } + fullindex := func() templ.Component { - return templates2.Index("s", "example.com", "converge") + return templates2.Index(access) } usage := func() templ.Component { - return templates2.UsageTab("s", "example.com", "converge") + return templates2.UsageTab(access) } render(dir, "fullindex.html", fullindex) diff --git a/pkg/models/convergeaccess.go b/pkg/models/convergeaccess.go new file mode 100644 index 0000000..007c321 --- /dev/null +++ b/pkg/models/convergeaccess.go @@ -0,0 +1,11 @@ +package models + +import "time" + +type ConvergeAccess struct { + // 's" when secure, "" otherwise + Secure string + HostPort string + Location *time.Location + Username string +} diff --git a/pkg/server/templates/index.templ b/pkg/server/templates/index.templ index 8914d90..947e97e 100644 --- a/pkg/server/templates/index.templ +++ b/pkg/server/templates/index.templ @@ -1,9 +1,12 @@ package templates -templ Index(secure string, host string, username string) { +import "converge/pkg/models" + + +templ Index(access models.ConvergeAccess) { @BasePage(0) { @About() - @Usage(secure, host, username) + @Usage(access) @Downloads() } } diff --git a/pkg/server/templates/usage.templ b/pkg/server/templates/usage.templ index 252f746..4fe25d8 100644 --- a/pkg/server/templates/usage.templ +++ b/pkg/server/templates/usage.templ @@ -1,8 +1,62 @@ package templates -templ Usage(secure string, host string, username string) { +import "converge/pkg/models" + +templ Usage(access models.ConvergeAccess) {
-

usage

+ + +

Usage

+ + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + +
+ + + +
+
+ +
+
+ +

usage old

Continuous integration jobs

@@ -12,14 +66,14 @@ templ Usage(secure string, host string, username string) {

{`
            # linux
-           `}curl http{secure}://{host}/static/agent > agent{`
+           `}curl http{access.Secure}://{access.HostPort}/static/agent > agent{`
            chmod 755 agent
-           `}./agent --id ID ws{secure}://{host}{`
+           `}./agent --id ID ws{access.Secure}://{access.HostPort}{`
            rm -f agent
 
            # windows
-           `}curl http{secure}://{host}/static/agent.exe > agent.exe{`
-           `}agent --id ID ws{secure}://{host}{`
+           `}curl http{access.Secure}://{access.HostPort}/static/agent.exe > agent.exe{`
+           `}agent --id ID ws{access.Secure}://{access.HostPort}{`
            del agent.exe
           `}

@@ -66,8 +120,8 @@ templ Usage(secure string, host string, username string) {

                                                                                                                               {`
-          `}ssh -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{secure}://{host}/client/ID"  { username }{"@localhost"}   {`
-          `}sftp -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{secure}://{host}/client/ID" { username }{"@localhost"}   {`
+          `}ssh -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.HostPort}/client/ID"  { access.Username }{"@localhost"}   {`
+          `}sftp -oServerAliveInterval=10 -oProxyCommand="wsproxy ws{access.Secure}://{access.HostPort}/client/ID" { access.Username }{"@localhost"}   {`
           `}

Local clients: using SSH with a local TCP forwarding proxy

@@ -91,8 +145,8 @@ templ Usage(secure string, host string, username string) {

                                                           {`
-          `}ssh -oServerAliveInterval=10 -p 10000 { username }{"@localhost"}          {`
-          `}sftp -oServerAliveInterval=10 -oPort=10000 { username }{"@localhost"}     {`
+          `}ssh -oServerAliveInterval=10 -p 10000 { access.Username }{"@localhost"}          {`
+          `}sftp -oServerAliveInterval=10 -oPort=10000 { access.Username }{"@localhost"}     {`
           `}

Remote shell usage

@@ -145,7 +199,7 @@ templ Usage(secure string, host string, username string) {

Authentication

- The { username } user above is configured in the + The { access.Username } user above is configured in the Converge server and is communicated to the agent when the agent is started as well as the password.

@@ -168,13 +222,91 @@ templ Usage(secure string, host string, username string) { Note that on windows you should not used quotes.

+ + +
} -templ UsageTab(secure string, host string, username string) { +templ UsageTab(access models.ConvergeAccess) { @BasePage(2) { - @Usage(secure, host, username) + @Usage(access) } }