From e05f5aa352f6ba55562a0afade0fa9046aeaf0d1 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Wed, 22 Apr 2020 23:52:04 +0200 Subject: [pkg] initialize service early for windows --- pkg/helper/darwin.go | 4 ++-- pkg/helper/helper.go | 20 +++++++++++++------- pkg/helper/linux.go | 7 +++++-- pkg/helper/windows.go | 27 +++++++++++++++++++-------- pkg/helper/windows_service.go | 12 ++++++++++-- 5 files changed, 49 insertions(+), 21 deletions(-) (limited to 'pkg/helper') diff --git a/pkg/helper/darwin.go b/pkg/helper/darwin.go index 3f8dc2f..e43c33c 100644 --- a/pkg/helper/darwin.go +++ b/pkg/helper/darwin.go @@ -87,11 +87,11 @@ func daemonize() { log.Print("bitmask-helper daemon started") } -func doHandleCommands(preferredPort int) { +func runServer(preferredPort int) { port := getFirstAvailablePortFrom(preferredPort) writePortToFile(port) bindAddr := "localhost:" + strconv.Itoa(port) - runCommandServer(bindAddr) + serveHTTP(bindAddr) } func getOpenvpnPath() string { diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go index b5b90bb..4fa88b2 100644 --- a/pkg/helper/helper.go +++ b/pkg/helper/helper.go @@ -33,7 +33,19 @@ type openvpnT struct { cmd *exec.Cmd } -func runCommandServer(bindAddr string) { +// startHelper is the main entrypoint. It can react to cli args (used to install or manage the service in windows), and +// eventually will start the http server. +func StartHelper(port int) { + initializeService(port) + parseCliArgs() + daemonize() + runServer(port) +} + +// serveHTTP will start the HTTP server that exposes the firewall and openvpn api. +// this can be called at different times by the different implementations of the helper. +func serveHTTP(bindAddr string) { + log.Println("Starting HTTP server at", bindAddr) openvpn := openvpnT{nil} http.HandleFunc("/openvpn/start", openvpn.start) http.HandleFunc("/openvpn/stop", openvpn.stop) @@ -45,12 +57,6 @@ func runCommandServer(bindAddr string) { log.Fatal(http.ListenAndServe(bindAddr, nil)) } -func ServeHTTP(port int) { - parseCliArgs() - daemonize() - doHandleCommands(port) -} - func (openvpn *openvpnT) start(w http.ResponseWriter, r *http.Request) { args, err := getArgs(r) if err != nil { diff --git a/pkg/helper/linux.go b/pkg/helper/linux.go index 5aa7e14..235351b 100644 --- a/pkg/helper/linux.go +++ b/pkg/helper/linux.go @@ -45,10 +45,13 @@ func parseCliArgs() { // linux helper does not reply to args } +func initializeService(port int) {} + func daemonize() {} -func doHandleCommands(port int) { - runCommandServer("localhost:" + strconv.Itoa(port)) +func runServer(port int) { + // defined in helper.go + serveHTTP("localhost:" + strconv.Itoa(port)) } func getOpenvpnPath() string { diff --git a/pkg/helper/windows.go b/pkg/helper/windows.go index 376b376..70c6d6a 100644 --- a/pkg/helper/windows.go +++ b/pkg/helper/windows.go @@ -37,15 +37,20 @@ const ( chocoOpenvpnPath = `C:\Program Files\OpenVPN\bin\openvpn.exe` ) +type httpConf struct { + BindAddr string +} + var ( platformOpenvpnFlags = []string{ "--script-security", "1", "--block-outside-dns", } - httpBindAddr string + httpServerConf = &httpConf{} ) func parseCliArgs() { + log.Println("Parsing CLI args...") isIntSess, err := svc.IsAnInteractiveSession() if err != nil { log.Fatalf("Failed to determine if we are running in an interactive session: %v", err) @@ -54,15 +59,18 @@ func parseCliArgs() { runService(svcName, false) return } + log.Println("Checking for admin") admin := isAdmin() fmt.Printf("Running as admin: %v\n", admin) if !admin { - log.Fatal("Needs to be run as administrator") + fmt.Println("Needs to be run as administrator") + os.Exit(2) } if len(os.Args) < 2 { usage("ERROR: no command specified") } cmd := strings.ToLower(os.Args[1]) + log.Println("cmd:", cmd) switch cmd { case "debug": runService(svcName, true) @@ -95,16 +103,19 @@ func usage(errmsg string) { os.Exit(2) } -func daemonize() {} - -// http server is called from within Execute in windows -func doHandleCommands(preferredPort int) { +// initializeService only initializes the server. +// we expect serveHTTP to be called from within Execute in windows +func initializeService(preferredPort int) { port := getFirstAvailablePortFrom(preferredPort) writePortToFile(port) - bindAddr := "localhost:" + strconv.Itoa(port) - httpBindAddr = bindAddr + httpServerConf.BindAddr = "localhost:" + strconv.Itoa(port) + log.Println("Command server initialized to listen on", httpServerConf.BindAddr) } +func daemonize() {} + +func runServer(port int) {} + func getOpenvpnPath() string { if _, err := os.Stat(openvpnPath); !os.IsNotExist(err) { return openvpnPath diff --git a/pkg/helper/windows_service.go b/pkg/helper/windows_service.go index df79d68..3675249 100644 --- a/pkg/helper/windows_service.go +++ b/pkg/helper/windows_service.go @@ -8,6 +8,7 @@ package helper import ( "fmt" + "log" "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/debug" @@ -22,13 +23,17 @@ func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes c const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue changes <- svc.Status{State: svc.StartPending} changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} - go runCommandServer(httpBindAddr) + + // defined in helper.go + // TODO should have a way to stop it -- + //go serveHTTP("localhost:7171") + log.Println("serving>>", httpServerConf.BindAddr) + go serveHTTP(httpServerConf.BindAddr) loop: for { select { case c := <-r: switch c.Cmd { - // TODO start?? case svc.Interrogate: changes <- c.CurrentStatus case svc.Stop, svc.Shutdown: @@ -44,6 +49,9 @@ loop: } func runService(name string, isDebug bool) { + + log.Println("Running service...") + var err error if isDebug { elog = debug.New(name) -- cgit v1.2.3