Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestions for server.go / aws-connect.sh #8

Open
JohnPolansky opened this issue Apr 24, 2021 · 1 comment
Open

Suggestions for server.go / aws-connect.sh #8

JohnPolansky opened this issue Apr 24, 2021 · 1 comment

Comments

@JohnPolansky
Copy link

Hey while using your great work to get around the issue of openvpn not supporting auth-federate and the larger saml tokens. I did find the fact that you had to start and stop the server.go by hand everytime. I guess one could leave it running, but I was curious to expand my meager skills with golang So I made some changes:

aws-connect.sh

diff --git a/aws-connect.sh b/aws-connect.sh
index 8f297fb..3a55e6c 100755
--- a/aws-connect.sh
+++ b/aws-connect.sh
@@ -27,6 +27,9 @@ SRV=$(dig a +short "${RAND}.${VPN_HOST}"|head -n1)
 # cleanup
 rm -f saml-response.txt

+# start the saml response server and background it
+go run server.go >> /tmp/aws-connect-saml-server.log 2>&1 &
+
 echo "Getting SAML redirect URL from the AUTH_FAILED response (host: ${SRV}:${PORT})"
 OVPN_OUT=$($OVPN_BIN --config "${OVPN_CONF}" --verb 3 \
      --proto "$PROTO" --remote "${SRV}" "${PORT}" \

The change is simple, I started the server.go when we run the aws-connect.sh and background it.

server.go

diff --git a/server.go b/server.go
index 48fe1f5..45908e9 100644
--- a/server.go
+++ b/server.go
@@ -6,31 +6,51 @@ import (
        "log"
        "net/http"
        "net/url"
+       "os"
+       "time"
 )

 func main() {
-       http.HandleFunc("/", SAMLServer)
-       log.Printf("Starting HTTP server at 127.0.0.1:35001")
-       http.ListenAndServe("127.0.0.1:35001", nil)
-}
+       var timeoutchan chan(bool) = make(chan bool)

-func SAMLServer(w http.ResponseWriter, r *http.Request) {
-       switch r.Method {
-       case "POST":
-               if err := r.ParseForm(); err != nil {
-                       fmt.Fprintf(w, "ParseForm() err: %v", err)
-                       return
-               }
-               SAMLResponse := r.FormValue("SAMLResponse")
-               if len(SAMLResponse) == 0 {
-                       log.Printf("SAMLResponse field is empty or not exists")
+       SAMLServer := func(w http.ResponseWriter, r *http.Request) {
+               switch r.Method {
+               case "POST":
+                       if err := r.ParseForm(); err != nil {
+                               fmt.Fprintf(w, "ParseForm() err: %v", err)
+                               return
+                       }
+                       SAMLResponse := r.FormValue("SAMLResponse")
+                       // fmt.Println(url.QueryEscape(SAMLResponse))
+
+                       if len(SAMLResponse) == 0 {
+                               log.Printf("SAMLResponse field is empty or not exists")
+                               return
+                       }
+                       ioutil.WriteFile("saml-response.txt", []byte(url.QueryEscape(SAMLResponse)), 0600)
+                       fmt.Fprintf(w, "Got SAMLResponse field, it is now safe to close this window\n")
+                       log.Printf("Got SAMLResponse field and saved it to the saml-response.txt file")
+                       timeoutchan <- true
                        return
+               default:
+                       fmt.Fprintf(w, "Error: POST method expected, %s recieved", r.Method)
                }
-               ioutil.WriteFile("saml-response.txt", []byte(url.QueryEscape(SAMLResponse)), 0600)
-               fmt.Fprintf(w, "Got SAMLResponse field, it is now safe to close this window\n")
-               log.Printf("Got SAMLResponse field and saved it to the saml-response.txt file")
-               return
-       default:
-               fmt.Fprintf(w, "Error: POST method expected, %s recieved", r.Method)
+       }
+
+       go func() {
+               http.HandleFunc("/", SAMLServer)
+               log.Printf("Starting HTTP server at 127.0.0.1:35001")
+               http.ListenAndServe("127.0.0.1:35001", nil)
+       }()
+
+       select {
+               case <-timeoutchan:
+                       log.Println("Work completed exiting...");
+                       os.Exit(0)
+                       break
+               case <-time.After(15 * time.Second):
+                       fmt.Println("Exiting due to 15 second timer... this likely indicates something went wrong.")
+                       os.Exit(1)
+                       break
        }
 }

Now as I mentioned golang isn't a strong language for me.. so I'm sure there are improvements. I made a few changes. first I added go routines to make the process more dynamic. Now when a user successfully does POST and gets a SAML response the server.go shuts down automatically. I did also add an automatic timeout for the server.go the idea was if something went wrong it would run forever just 15 seconds, but after thinking about it.. This could be an issue because if your browser isn't caching the SAML provider tokens, u will need to login which likely will take more than 15 seconds.

Anyway I thought I would share the idea and see what you think. I also am submitting another ticket.. with a new spin that doesn't require server.go or listening for a POST response, at least for OKTA SAML provider.

If you don't like the changes no worries, just close the ticket just wanted to share the ideas.

@samm-git
Copy link
Owner

samm-git commented May 4, 2021

thats sounds interesting. What i am thinking - may be we can use systemd to start it when there is connection to that port. Or launchd on macos. Need to play with it a little

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants