From 179b82149dc7108125fc0d32a0a37e59e7608c74 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 11 Apr 2022 14:24:10 -0500 Subject: [PATCH 01/19] various small fixes --- Makefile | 69 +++++++++++--------------- cmd/skywire-cli/commands/config/gen.go | 17 ++++++- cmd/skywire-visor/commands/root.go | 17 +++++-- cmd/skywire-visor/commands/systray.go | 5 +- local/.gitignore | 4 ++ scripts/_apps/vpn-client-systray | 2 + scripts/_apps/vpn-server-systray | 2 + 7 files changed, 71 insertions(+), 45 deletions(-) create mode 100644 local/.gitignore create mode 100755 scripts/_apps/vpn-client-systray create mode 100755 scripts/_apps/vpn-server-systray diff --git a/Makefile b/Makefile index c51d52e48..b0ae358c2 100644 --- a/Makefile +++ b/Makefile @@ -152,6 +152,7 @@ snapshot-clean: ## Cleans snapshot / release rm -rf ./dist host-apps: ## Build app + test -d apps && rm -r apps || true mkdir -p ./apps ${OPTS} go build ${BUILD_OPTS} -o ./apps/ ./cmd/apps/skychat ${OPTS} go build ${BUILD_OPTS} -o ./apps/ ./cmd/apps/skysocks @@ -180,6 +181,7 @@ host-apps-systray-windows: # Static Apps host-apps-static: ## Build app + test -d apps && rm -r apps || true mkdir -p ./apps ${STATIC_OPTS} go build -trimpath --ldflags '-linkmode external -extldflags "-static" -buildid=' -o ./apps/ ./cmd/apps/skychat ${STATIC_OPTS} go build -trimpath --ldflags '-linkmode external -extldflags "-static" -buildid=' -o ./apps/ ./cmd/apps/skysocks @@ -233,68 +235,57 @@ install-deps-ui: ## Install the UI dependencies run: ## Run skywire visor with skywire-config.json, and start a browser if running a hypervisor ./skywire-visor -bc ./skywire-config.json -## Run skywire from source, without compiling binaries - requires skywire cloned -run-source: +## Prepare to run skywire from source, without compiling binaries +prepare: test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* + mkdir -p apps + ln ./scripts/_apps/skychat ./apps/ + ln ./scripts/_apps/skysocks ./apps/ + ln ./scripts/_apps/skysocks-client ./apps/ + ln ./scripts/_apps/vpn-server ./apps/ + ln ./scripts/_apps/vpn-client ./apps/ + chmod +x ./apps/* sudo echo "sudo cache" + +prepare-systray: prepare + rm apps/vpn* + ln -f ./scripts/_apps/vpn-server-systray ./apps/vpn-server + ln -f ./scripts/_apps/vpn-client-systray ./apps/vpn-client + +## Run skywire from source, without compiling binaries - requires skywire cloned +run-source: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -in | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source, without compiling binaries - requires skywire cloned -run-vpnsrv: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-vpnsrv: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -in --servevpn | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source with test endpoints -run-source-test: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-source-test: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -nit | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source, with vpn server enabled -run-vpnsrv-test: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-vpnsrv-test: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -nit --servevpn | go run ./cmd/skywire-visor/skywire-visor.go -nb || true +## Run skywire from source, with vpn server enabled +run-systray-test: prepare-systray + go run -tags systray ./cmd/skywire-cli/skywire-cli.go config gen -nit | go run -tags systray ./cmd/skywire-visor/skywire-visor.go -nb || true + ## Run skywire from source with dmsghttp config -run-source-dmsghttp: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-source-dmsghttp: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -din | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source with dmsghttp config and vpn server -run-vpnsrv-dmsghttp: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-vpnsrv-dmsghttp: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -din --servevpn | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source with dmsghttp config and test endpoints -run-source-dmsghttp-test: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-source-dmsghttp-test: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -dint | go run ./cmd/skywire-visor/skywire-visor.go -nb || true ## Run skywire from source with dmsghttp config, vpn server, and test endpoints -run-vpnsrv-dmsghttp-test: - test -d apps && rm -r apps || true - ln -s scripts/_apps apps - chmod +x apps/* - sudo echo "sudo cache" +run-vpnsrv-dmsghttp-test: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -dint --servevpn | go run ./cmd/skywire-visor/skywire-visor.go -nb || true lint-ui: ## Lint the UI code diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 1a6fb1296..ea5c98da2 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -58,30 +58,45 @@ func init() { RootCmd.AddCommand(genConfigCmd) genConfigCmd.Flags().StringVarP(&serviceConfURL, "url", "a", svcconf, "services conf") + hiddenflags = append(hiddenflags, "url") genConfigCmd.Flags().BoolVarP(&bestProtocol, "bestproto", "b", false, "best protocol (dmsg | direct) based on location") genConfigCmd.Flags().BoolVarP(&disableauth, "noauth", "c", false, "disable authentication for hypervisor UI") + hiddenflags = append(hiddenflags, "noauth") genConfigCmd.Flags().BoolVarP(&dmsgHTTP, "dmsghttp", "d", false, "use dmsg connection to skywire services") + hiddenflags = append(hiddenflags, "dmsghttp") genConfigCmd.Flags().BoolVarP(&enableauth, "auth", "e", false, "enable auth on hypervisor UI") + hiddenflags = append(hiddenflags, "auth") genConfigCmd.Flags().BoolVarP(&force, "force", "f", false, "remove pre-existing config") + hiddenflags = append(hiddenflags, "force") genConfigCmd.Flags().StringVarP(&disableApps, "disableapps", "g", "", "comma separated list of apps to disable") + hiddenflags = append(hiddenflags, "disableapps") genConfigCmd.Flags().BoolVarP(&hypervisor, "ishv", "i", false, "local hypervisor configuration") genConfigCmd.Flags().StringVarP(&hypervisorPKs, "hvpks", "j", "", "list of public keys to use as hypervisor") genConfigCmd.Flags().StringVarP(&selectedOS, "os", "k", skyenv.OS, "(linux / macos / windows) paths") + hiddenflags = append(hiddenflags, "os") genConfigCmd.Flags().BoolVarP(&stdout, "stdout", "n", false, "write config to stdout") + hiddenflags = append(hiddenflags, "stdout") genConfigCmd.Flags().StringVarP(&output, "out", "o", skyenv.ConfigName, "output config") genConfigCmd.Flags().BoolVarP(&pkgEnv, "package", "p", false, "use paths for package "+skyenv.SkywirePath) genConfigCmd.Flags().BoolVarP(&publicRPC, "publicrpc", "q", false, "allow rpc requests from LAN") + hiddenflags = append(hiddenflags, "publicrpc") genConfigCmd.Flags().BoolVarP(®en, "regen", "r", false, "re-generate existing config & retain keys") genConfigCmd.Flags().VarP(&sk, "sk", "s", "a random key is generated if unspecified\n\r") + hiddenflags = append(hiddenflags, "sk") genConfigCmd.Flags().BoolVarP(&testEnv, "testenv", "t", false, "use test deployment "+testconf) + hiddenflags = append(hiddenflags, "testenv") genConfigCmd.Flags().BoolVarP(&vpnServerEnable, "servevpn", "v", false, "enable vpn server") + hiddenflags = append(hiddenflags, "servevpn") genConfigCmd.Flags().BoolVarP(&hide, "hide", "w", false, "dont print the config to the terminal") + hiddenflags = append(hiddenflags, "hide") genConfigCmd.Flags().BoolVarP(&retainHypervisors, "retainhv", "x", false, "retain existing hypervisors with regen") + hiddenflags = append(hiddenflags, "retainhv") genConfigCmd.Flags().StringVar(&ver, "version", "", "custom version testing override") + hiddenflags = append(hiddenflags, "version") genConfigCmd.Flags().BoolVar(&all, "all", false, "show all flags") genConfigCmd.Flags().StringVar(&print, "print", "", "parse test ; read config from file & print") + hiddenflags = append(hiddenflags, "print") - hiddenflags = []string{"url", "print", "noauth", "dmsghttp", "auth", "force", "disableapps", "os", "stdout", "publicrpc", "sk", "testenv", "servevpn", "hide", "retainhv", "print", "version"} for _, j := range hiddenflags { genConfigCmd.Flags().MarkHidden(j) //nolint } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 18c2ec506..978849d62 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -80,20 +80,29 @@ func init() { rootCmd.Flags().BoolVarP(&hypervisorUI, "hvui", "i", false, "run as hypervisor") rootCmd.Flags().BoolVarP(&launchBrowser, "browser", "b", false, "open hypervisor ui in default web browser") rootCmd.Flags().StringVarP(&remoteHypervisorPKs, "hv", "j", "", "add remote hypervisor PKs at runtime") + hiddenflags = append(hiddenflags, "hv") rootCmd.Flags().BoolVarP(&disableHypervisorPKs, "xhv", "k", false, "disable remote hypervisors set in config file") + hiddenflags = append(hiddenflags, "xhv") rootCmd.Flags().BoolVarP(&stdin, "stdin", "n", false, "read config from stdin") + hiddenflags = append(hiddenflags, "stdin") if skyenv.OS == "linux" { rootCmd.Flags().BoolVar(&pkg, "ph", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirejson) + hiddenflags = append(hiddenflags, "ph") rootCmd.Flags().BoolVar(&pkg1, "pv", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirevisorjson) + hiddenflags = append(hiddenflags, "pv") } rootCmd.Flags().StringVarP(&pprofMode, "pprofmode", "p", "", "pprof mode: cpu, mem, mutex, block, trace, http") + hiddenflags = append(hiddenflags, "pprofmode") rootCmd.Flags().StringVarP(&pprofAddr, "pprofaddr", "q", "localhost:6060", "pprof http port") + hiddenflags = append(hiddenflags, "pprofaddr") rootCmd.Flags().StringVarP(&tag, "tag", "t", "skywire", "logging tag") + hiddenflags = append(hiddenflags, "tag") rootCmd.Flags().StringVarP(&syslogAddr, "syslog", "y", "", "syslog server address. E.g. localhost:514") + hiddenflags = append(hiddenflags, "syslog") rootCmd.Flags().StringVarP(&completion, "completion", "z", "", "[ bash | zsh | fish | powershell ]") + hiddenflags = append(hiddenflags, "completion") rootCmd.Flags().BoolVar(&all, "all", false, "show all flags") - hiddenflags = []string{"hv", "xhv", "stdin", "pprofmode", "pprofaddr", "tag", "syslog", "completion", "ph", "pv"} for _, j := range hiddenflags { rootCmd.Flags().MarkHidden(j) //nolint } @@ -266,7 +275,7 @@ var rootCmd = &cobra.Command{ Version: buildinfo.Version(), } -func runVisor() { +func runVisor(conf *visorconfig.V1) { var ok bool log := initLogger(tag, syslogAddr) store, hook := logstore.MakeStore(runtimeLogMaxEntries) @@ -275,7 +284,9 @@ func runVisor() { stopPProf := initPProf(log, tag, pprofMode, pprofAddr) defer stopPProf() - conf := initConfig(log, confPath) + if conf == nil { + conf = initConfig(log, confPath) + } if disableHypervisorPKs { conf.Hypervisors = []cipher.PubKey{} diff --git a/cmd/skywire-visor/commands/systray.go b/cmd/skywire-visor/commands/systray.go index cee11b429..5acf3a9db 100644 --- a/cmd/skywire-visor/commands/systray.go +++ b/cmd/skywire-visor/commands/systray.go @@ -19,12 +19,13 @@ func runApp(args ...string) { l.WithError(err).Fatalln("Failed to read system tray icon") } + conf := initConfig(l, confPath) + go func() { - runVisor() + runVisor(conf) systray.Quit() }() - conf := initConfig(l, confPath) systray.Run(gui.GetOnGUIReady(sysTrayIcon, conf), gui.OnGUIQuit) } diff --git a/local/.gitignore b/local/.gitignore new file mode 100644 index 000000000..5e7d2734c --- /dev/null +++ b/local/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/scripts/_apps/vpn-client-systray b/scripts/_apps/vpn-client-systray new file mode 100755 index 000000000..93eaacc2d --- /dev/null +++ b/scripts/_apps/vpn-client-systray @@ -0,0 +1,2 @@ +#!/bin/bash +sudo go run -tags systray ../../cmd/apps/vpn-client/vpn-client.go diff --git a/scripts/_apps/vpn-server-systray b/scripts/_apps/vpn-server-systray new file mode 100755 index 000000000..e94192e12 --- /dev/null +++ b/scripts/_apps/vpn-server-systray @@ -0,0 +1,2 @@ +#!/bin/bash +sudo go run -tags systray ../../cmd/apps/vpn-server/vpn-server.go From b12e9543360899de9727af151251df4db2448470 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 11 Apr 2022 14:26:07 -0500 Subject: [PATCH 02/19] make format check --- cmd/skywire-visor/commands/nosystray.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/skywire-visor/commands/nosystray.go b/cmd/skywire-visor/commands/nosystray.go index 86a050fa7..0a61b983a 100644 --- a/cmd/skywire-visor/commands/nosystray.go +++ b/cmd/skywire-visor/commands/nosystray.go @@ -10,7 +10,7 @@ import ( ) func runApp() { - runVisor() + runVisor(nil) } // setStopFunction sets the stop function From 0ec48690e65450d1586d0a44046b96287521885c Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 11 Apr 2022 14:35:07 -0500 Subject: [PATCH 03/19] run-systray makefile directive --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index b0ae358c2..f390b726c 100644 --- a/Makefile +++ b/Makefile @@ -256,6 +256,10 @@ prepare-systray: prepare run-source: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -in | go run ./cmd/skywire-visor/skywire-visor.go -nb || true +## Run skywire from source, with vpn server enabled +run-systray: prepare-systray + go run -tags systray ./cmd/skywire-cli/skywire-cli.go config gen -ni | go run -tags systray ./cmd/skywire-visor/skywire-visor.go -nb || true + ## Run skywire from source, without compiling binaries - requires skywire cloned run-vpnsrv: prepare go run ./cmd/skywire-cli/skywire-cli.go config gen -in --servevpn | go run ./cmd/skywire-visor/skywire-visor.go -nb || true From 998b5e09068c2aa10e1c8dce55fe1d062355af83 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 11 Apr 2022 18:03:34 -0500 Subject: [PATCH 04/19] disable systray when visor is run as root - browser cannot launch as root --- cmd/skywire-visor/commands/root.go | 22 ++++---- cmd/skywire-visor/commands/systray.go | 4 +- cmd/skywire-visor/commands/systray_linux.go | 59 +++++++++++++++++++++ 3 files changed, 72 insertions(+), 13 deletions(-) create mode 100644 cmd/skywire-visor/commands/systray_linux.go diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 978849d62..46e2b8361 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -74,11 +74,21 @@ var ( ) func init() { + thisUser, err := user.Current() + if err != nil { + panic(err) + } + if thisUser.Username == "root" { + root = true + } + rootCmd.Flags().SortFlags = false rootCmd.Flags().StringVarP(&confPath, "config", "c", skyenv.ConfigName, "config file to use") rootCmd.Flags().BoolVarP(&hypervisorUI, "hvui", "i", false, "run as hypervisor") - rootCmd.Flags().BoolVarP(&launchBrowser, "browser", "b", false, "open hypervisor ui in default web browser") + if ((skyenv.OS == "linux") && !root) || ((skyenv.OS == "mac") && !root) || (skyenv.OS == "win") { + rootCmd.Flags().BoolVarP(&launchBrowser, "browser", "b", false, "open hypervisor ui in default web browser") + } rootCmd.Flags().StringVarP(&remoteHypervisorPKs, "hv", "j", "", "add remote hypervisor PKs at runtime") hiddenflags = append(hiddenflags, "hv") rootCmd.Flags().BoolVarP(&disableHypervisorPKs, "xhv", "k", false, "disable remote hypervisors set in config file") @@ -197,16 +207,6 @@ var rootCmd = &cobra.Command{ log.WithError(err).Fatal() } workDir = path - //determine if process has root permissions - thisUser, err := user.Current() - if err != nil { - log.Error("Unable to get current user: %s", err) - } - if (skyenv.OS == "linux") || (skyenv.OS == "mac") { - if thisUser.Username == "root" { - root = true - } - } //retrieve build info visorBuildInfo = buildinfo.Get() if visorBuildInfo.Version == "unknown" { diff --git a/cmd/skywire-visor/commands/systray.go b/cmd/skywire-visor/commands/systray.go index 5acf3a9db..95dc0e677 100644 --- a/cmd/skywire-visor/commands/systray.go +++ b/cmd/skywire-visor/commands/systray.go @@ -1,5 +1,5 @@ -//go:build systray -// +build systray +//go:build systray && !linux +// +build systray,!linux package commands diff --git a/cmd/skywire-visor/commands/systray_linux.go b/cmd/skywire-visor/commands/systray_linux.go new file mode 100644 index 000000000..4ebf4d8b6 --- /dev/null +++ b/cmd/skywire-visor/commands/systray_linux.go @@ -0,0 +1,59 @@ +//go:build systray && linux +// +build systray,linux + +package commands + +import ( + "context" + + "github.com/getlantern/systray" + "github.com/skycoin/skycoin/src/util/logging" + + "github.com/skycoin/skywire/internal/gui" +) + +func runApp(args ...string) { + //systray app cannot launch browser as root + if root { + runVisor(nil) + } else { + l := logging.NewMasterLogger() + sysTrayIcon, err := gui.ReadSysTrayIcon() + if err != nil { + l.WithError(err).Fatalln("Failed to read system tray icon") + } + conf := initConfig(l, confPath) + go func() { + runVisor(conf) + systray.Quit() + }() + systray.Run(gui.GetOnGUIReady(sysTrayIcon, conf), gui.OnGUIQuit) + } +} + +func setStopFunction(log *logging.MasterLogger, cancel context.CancelFunc, fn func() error) { + stopVisorWg.Add(1) + defer stopVisorWg.Done() + + stopVisorFn = func() { + if err := fn(); err != nil { + log.WithError(err).Error("Visor closed with error.") + } + cancel() + stopVisorWg.Wait() + } + + //systray app cannot launch browser as root + if root { + gui.SetStopVisorFn(func() { + stopVisorFn() + }) + } + +} + +func quitSystray() { + if root { + systray.Quit() + } +} From b158522464cfabdf176898b8454628c5b5a8a34d Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Mon, 11 Apr 2022 22:03:01 -0500 Subject: [PATCH 05/19] require root user to run VPN client & server --- cmd/apps/skychat/{chat.go => skychat.go} | 112 ++++++--- cmd/apps/skysocks-client/skysocks-client.go | 146 +++++++---- cmd/apps/skysocks/skysocks.go | 117 ++++++--- cmd/apps/vpn-client/vpn-client.go | 259 ++++++++++++-------- cmd/apps/vpn-server/vpn-server.go | 163 +++++++----- 5 files changed, 507 insertions(+), 290 deletions(-) rename cmd/apps/skychat/{chat.go => skychat.go} (64%) diff --git a/cmd/apps/skychat/chat.go b/cmd/apps/skychat/skychat.go similarity index 64% rename from cmd/apps/skychat/chat.go rename to cmd/apps/skychat/skychat.go index b6e2f5698..05a7a83a1 100644 --- a/cmd/apps/skychat/chat.go +++ b/cmd/apps/skychat/skychat.go @@ -7,7 +7,6 @@ import ( "context" "embed" "encoding/json" - "flag" "fmt" "io/fs" "net" @@ -17,8 +16,10 @@ import ( "sync" "time" + cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" "github.com/skycoin/skycoin/src/util/logging" + "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/cipher" @@ -34,62 +35,95 @@ const ( port = routing.Port(1) ) -var log = logging.MustGetLogger("chat") -var addr = flag.String("addr", ":8001", "address to bind") -var r = netutil.NewRetrier(log, 50*time.Millisecond, netutil.DefaultMaxBackoff, 5, 2) - var ( - appC *app.Client - clientCh chan string - conns map[cipher.PubKey]net.Conn // Chat connections - connsMu sync.Mutex + // the go embed static points to skywire/cmd/apps/skychat/static + //go:embed static + embededFiles embed.FS + log = logging.MustGetLogger("chat") + r = netutil.NewRetrier(log, 50*time.Millisecond, netutil.DefaultMaxBackoff, 5, 2) + addr string + appC *app.Client + clientCh chan string + conns map[cipher.PubKey]net.Conn // Chat connections + connsMu sync.Mutex ) -// the go embed static points to skywire/cmd/apps/skychat/static +func init() { + rootCmd.Flags().SortFlags = false + rootCmd.Flags().StringVarP(&addr, "addr", "a", ":8001", "address to bind") +} -//go:embed static -var embededFiles embed.FS +var rootCmd = &cobra.Command{ + Use: "skysocks", + Short: "Skywire SOCKS5 Proxy Server", + Long: ` + ┌─┐┬┌─┬ ┬┌─┐┬ ┬┌─┐┌┬┐ + └─┐├┴┐└┬┘│ ├─┤├─┤ │ + └─┘┴ ┴ ┴ └─┘┴ ┴┴ ┴ ┴ `, + Run: func(_ *cobra.Command, _ []string) { + appC = app.NewClient(nil) + defer appC.Close() + + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + fmt.Printf("Failed to output build info: %v", err) + } -func main() { - appC = app.NewClient(nil) - defer appC.Close() + fmt.Print("Successfully started skychat.") - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - fmt.Printf("Failed to output build info: %v", err) - } + clientCh = make(chan string) + defer close(clientCh) - flag.Parse() - fmt.Print("Successfully started skychat.") + conns = make(map[cipher.PubKey]net.Conn) + go listenLoop() - clientCh = make(chan string) - defer close(clientCh) + if runtime.GOOS == "windows" { + ipcClient, err := ipc.StartClient(skyenv.SkychatName, nil) + if err != nil { + fmt.Printf("Error creating ipc server for skychat client: %v\n", err) + os.Exit(1) + } + go handleIPCSignal(ipcClient) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - conns = make(map[cipher.PubKey]net.Conn) - go listenLoop() + http.Handle("/", http.FileServer(getFileSystem())) + http.HandleFunc("/message", messageHandler(ctx)) + http.HandleFunc("/sse", sseHandler) - if runtime.GOOS == "windows" { - ipcClient, err := ipc.StartClient(skyenv.SkychatName, nil) + fmt.Print("Serving HTTP on", addr) + err := http.ListenAndServe(addr, nil) if err != nil { - fmt.Printf("Error creating ipc server for skychat client: %v\n", err) + fmt.Println(err) os.Exit(1) } - go handleIPCSignal(ipcClient) - } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - http.Handle("/", http.FileServer(getFileSystem())) - http.HandleFunc("/message", messageHandler(ctx)) - http.HandleFunc("/sse", sseHandler) + }, +} - fmt.Print("Serving HTTP on", *addr) - err := http.ListenAndServe(*addr, nil) - if err != nil { +// Execute executes root CLI command. +func Execute() { + cc.Init(&cc.Config{ + RootCmd: rootCmd, + Headings: cc.HiBlue + cc.Bold, + Commands: cc.HiBlue + cc.Bold, + CmdShortDescr: cc.HiBlue, + Example: cc.HiBlue + cc.Italic, + ExecName: cc.HiBlue + cc.Bold, + Flags: cc.HiBlue + cc.Bold, + FlagsDescr: cc.HiBlue, + NoExtraNewlines: true, + NoBottomNewline: true, + }) + + if err := rootCmd.Execute(); err != nil { fmt.Println(err) - os.Exit(1) } } +func main() { + Execute() +} + func listenLoop() { l, err := appC.Listen(netType, port) if err != nil { diff --git a/cmd/apps/skysocks-client/skysocks-client.go b/cmd/apps/skysocks-client/skysocks-client.go index ac753691c..5d8f1dbc8 100644 --- a/cmd/apps/skysocks-client/skysocks-client.go +++ b/cmd/apps/skysocks-client/skysocks-client.go @@ -5,13 +5,15 @@ package main import ( "context" - "flag" + "fmt" "io" "net" "os" "time" + cc "github.com/ivanpirog/coloredcobra" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/cipher" @@ -28,9 +30,78 @@ const ( socksPort = routing.Port(3) ) -var log = logrus.New() +var ( + log = logrus.New() + r = netutil.NewRetrier(log, time.Second, netutil.DefaultMaxBackoff, 0, 1) + serverPK string + addr string +) + +func init() { + rootCmd.Flags().SortFlags = false + + rootCmd.Flags().StringVarP(&addr, "addr", "a", skyenv.SkysocksClientAddr, "Client address to listen on") + rootCmd.Flags().StringVarP(&serverPK, "srv", "q", "", "PubKey of the server to connect to") +} + +var rootCmd = &cobra.Command{ + Use: "skysocks", + Short: "Skywire SOCKS5 Proxy Server", + Long: ` + ┌─┐┬┌─┬ ┬┌─┐┌─┐┌─┐┬┌─┌─┐ ┌─┐┬ ┬┌─┐┌┐┌┌┬┐ + └─┐├┴┐└┬┘└─┐│ ││ ├┴┐└─┐───│ │ │├┤ │││ │ + └─┘┴ ┴ ┴ └─┘└─┘└─┘┴ ┴└─┘ └─┘┴─┘┴└─┘┘└┘ ┴ `, + Run: func(_ *cobra.Command, _ []string) { + appC := app.NewClient(nil) + defer appC.Close() + + skysocks.Log = log + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + log.Printf("Failed to output build info: %v", err) + } + + if serverPK == "" { + log.Warn("Empty server PubKey. Exiting") + return + } -var r = netutil.NewRetrier(log, time.Second, netutil.DefaultMaxBackoff, 0, 1) + pk := cipher.PubKey{} + if err := pk.UnmarshalText([]byte(serverPK)); err != nil { + log.Fatal("Invalid server PubKey: ", err) + } + + for { + conn, err := dialServer(ctx, appC, pk) + if err != nil { + log.Fatalf("Failed to dial to a server: %v", err) + } + + log.Printf("Connected to %v\n", pk) + + client, err := skysocks.NewClient(conn) + if err != nil { + log.Fatal("Failed to create a new client: ", err) + } + + log.Printf("Serving proxy client %v\n", addr) + + if err := client.ListenAndServe(addr); err != nil { + log.Errorf("Error serving proxy client: %v\n", err) + } + + // need to filter this out, cause usually client failure means app conn is already closed + if err := conn.Close(); err != nil && err != io.ErrClosedPipe { + log.Errorf("Error closing app conn: %v\n", err) + } + + log.Println("Reconnecting to skysocks server") + } + }, +} func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.Conn, error) { var conn net.Conn @@ -50,57 +121,26 @@ func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.C return conn, nil } -func main() { - appC := app.NewClient(nil) - defer appC.Close() - - skysocks.Log = log - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - log.Printf("Failed to output build info: %v", err) - } - - var addr = flag.String("addr", skyenv.SkysocksClientAddr, "Client address to listen on") - var serverPK = flag.String("srv", "", "PubKey of the server to connect to") - flag.Parse() - - if *serverPK == "" { - log.Warn("Empty server PubKey. Exiting") - return - } +// Execute executes root CLI command. +func Execute() { + cc.Init(&cc.Config{ + RootCmd: rootCmd, + Headings: cc.HiBlue + cc.Bold, + Commands: cc.HiBlue + cc.Bold, + CmdShortDescr: cc.HiBlue, + Example: cc.HiBlue + cc.Italic, + ExecName: cc.HiBlue + cc.Bold, + Flags: cc.HiBlue + cc.Bold, + FlagsDescr: cc.HiBlue, + NoExtraNewlines: true, + NoBottomNewline: true, + }) - pk := cipher.PubKey{} - if err := pk.UnmarshalText([]byte(*serverPK)); err != nil { - log.Fatal("Invalid server PubKey: ", err) + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) } +} - for { - conn, err := dialServer(ctx, appC, pk) - if err != nil { - log.Fatalf("Failed to dial to a server: %v", err) - } - - log.Printf("Connected to %v\n", pk) - - client, err := skysocks.NewClient(conn) - if err != nil { - log.Fatal("Failed to create a new client: ", err) - } - - log.Printf("Serving proxy client %v\n", *addr) - - if err := client.ListenAndServe(*addr); err != nil { - log.Errorf("Error serving proxy client: %v\n", err) - } - - // need to filter this out, cause usually client failure means app conn is already closed - if err := conn.Close(); err != nil && err != io.ErrClosedPipe { - log.Errorf("Error closing app conn: %v\n", err) - } - - log.Println("Reconnecting to skysocks server") - } +func main() { + Execute() } diff --git a/cmd/apps/skysocks/skysocks.go b/cmd/apps/skysocks/skysocks.go index 53eb71a7b..5bf56867f 100644 --- a/cmd/apps/skysocks/skysocks.go +++ b/cmd/apps/skysocks/skysocks.go @@ -4,14 +4,15 @@ proxy server app for skywire visor package main import ( - "flag" "fmt" "os" "os/signal" "runtime" + cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire/internal/skysocks" @@ -26,57 +27,95 @@ const ( port routing.Port = 3 ) -var log = logrus.New() - -func main() { - appC := app.NewClient(nil) - defer appC.Close() - - skysocks.Log = log - - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - fmt.Printf("Failed to output build info: %v", err) - } +var ( + log = logrus.New() + passcode string +) - var passcode = flag.String("passcode", "", "Authorize user against this passcode") - flag.Parse() +func init() { + rootCmd.Flags().SortFlags = false - srv, err := skysocks.NewServer(*passcode, log) - if err != nil { - log.Fatal("Failed to create a new server: ", err) - } + rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") +} - l, err := appC.Listen(netType, port) - if err != nil { - log.Fatalf("Error listening network %v on port %d: %v\n", netType, port, err) - } +var rootCmd = &cobra.Command{ + Use: "skysocks", + Short: "Skywire SOCKS5 Proxy Server", + Long: ` + ┌─┐┬┌─┬ ┬┌─┐┌─┐┌─┐┬┌─┌─┐ + └─┐├┴┐└┬┘└─┐│ ││ ├┴┐└─┐ + └─┘┴ ┴ ┴ └─┘└─┘└─┘┴ ┴└─┘`, + Run: func(_ *cobra.Command, _ []string) { + appC := app.NewClient(nil) + defer appC.Close() + + skysocks.Log = log + + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + fmt.Printf("Failed to output build info: %v", err) + } - fmt.Println("Starting serving proxy server") + srv, err := skysocks.NewServer(passcode, log) + if err != nil { + log.Fatal("Failed to create a new server: ", err) + } - if runtime.GOOS == "windows" { - ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) + l, err := appC.Listen(netType, port) if err != nil { - fmt.Printf("Error creating ipc server for VPN client: %v\n", err) - os.Exit(1) + log.Fatalf("Error listening network %v on port %d: %v\n", netType, port, err) } - go srv.ListenIPC(ipcClient) - } else { - termCh := make(chan os.Signal, 1) - signal.Notify(termCh, os.Interrupt) - go func() { - <-termCh + fmt.Println("Starting serving proxy server") - if err := srv.Close(); err != nil { - fmt.Println(err) + if runtime.GOOS == "windows" { + ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) + if err != nil { + fmt.Printf("Error creating ipc server for VPN client: %v\n", err) os.Exit(1) } - }() + go srv.ListenIPC(ipcClient) + } else { + termCh := make(chan os.Signal, 1) + signal.Notify(termCh, os.Interrupt) - } + go func() { + <-termCh + + if err := srv.Close(); err != nil { + fmt.Println(err) + os.Exit(1) + } + }() + + } + + if err := srv.Serve(l); err != nil { + fmt.Println(err) + os.Exit(1) + } + }, +} - if err := srv.Serve(l); err != nil { +// Execute executes root CLI command. +func Execute() { + cc.Init(&cc.Config{ + RootCmd: rootCmd, + Headings: cc.HiBlue + cc.Bold, + Commands: cc.HiBlue + cc.Bold, + CmdShortDescr: cc.HiBlue, + Example: cc.HiBlue + cc.Italic, + ExecName: cc.HiBlue + cc.Bold, + Flags: cc.HiBlue + cc.Bold, + FlagsDescr: cc.HiBlue, + NoExtraNewlines: true, + NoBottomNewline: true, + }) + + if err := rootCmd.Execute(); err != nil { fmt.Println(err) - os.Exit(1) } } + +func main() { + Execute() +} diff --git a/cmd/apps/vpn-client/vpn-client.go b/cmd/apps/vpn-client/vpn-client.go index 2e61ab501..646308dd4 100644 --- a/cmd/apps/vpn-client/vpn-client.go +++ b/cmd/apps/vpn-client/vpn-client.go @@ -1,15 +1,17 @@ package main import ( - "flag" "fmt" "net" "os" "os/signal" + "os/user" "runtime" "syscall" + cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" + "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire/internal/vpn" @@ -19,142 +21,193 @@ import ( ) var ( - serverPKStr = flag.String("srv", "", "PubKey of the server to connect to") - localPKStr = flag.String("pk", "", "Local PubKey") - localSKStr = flag.String("sk", "", "Local SecKey") - passcode = flag.String("passcode", "", "Passcode to authenticate connection") - killswitch = flag.Bool("killswitch", false, "If set, the Internet won't be restored during reconnection attempts") + serverPKStr string + localPKStr string + localSKStr string + passcode string + killswitch bool ) -func main() { - flag.Parse() - - if *serverPKStr == "" { - // TODO(darkrengarius): fix args passage for Windows - //*serverPKStr = "03e9019b3caa021dbee1c23e6295c6034ab4623aec50802fcfdd19764568e2958d" - fmt.Println("VPN server pub key is missing") - os.Exit(1) +func init() { + thisUser, err := user.Current() + if err != nil { + panic(err) } - - serverPK := cipher.PubKey{} - if err := serverPK.UnmarshalText([]byte(*serverPKStr)); err != nil { - fmt.Printf("Invalid VPN server pub key: %v\n", err) + if (thisUser.Username != "root") && ((skyenv.OS == "linux") || (skyenv.OS == "mac")) { + fmt.Println("vpn client must be run as root") os.Exit(1) } - localPK := cipher.PubKey{} - if *localPKStr != "" { - if err := localPK.UnmarshalText([]byte(*localPKStr)); err != nil { - fmt.Printf("Invalid local PK: %v\n", err) + rootCmd.Flags().SortFlags = false + + rootCmd.Flags().StringVarP(&serverPKStr, "srv", "q", "", "PubKey of the server to connect to") + rootCmd.Flags().StringVarP(&localPKStr, "pk", "p", "", "Local PubKey") + rootCmd.Flags().StringVarP(&localSKStr, "sk", "s", "", "Local SecKey") + rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") + rootCmd.Flags().BoolVarP(&killswitch, "killswitch", "k", false, "If set, the Internet won't be restored during reconnection attempts") + +} + +var rootCmd = &cobra.Command{ + Use: "vpn-client", + Short: "Skywire VPN Client", + Long: ` + ┬ ┬┌─┐┌┐┌ ┌─┐┬ ┬┌─┐┌┐┌┌┬┐ + └┐┌┘├─┘│││───│ │ │├┤ │││ │ + └┘ ┴ ┘└┘ └─┘┴─┘┴└─┘┘└┘ ┴ `, + Run: func(_ *cobra.Command, _ []string) { + if serverPKStr == "" { + // TODO(darkrengarius): fix args passage for Windows + //*serverPKStr = "03e9019b3caa021dbee1c23e6295c6034ab4623aec50802fcfdd19764568e2958d" + fmt.Println("VPN server pub key is missing") os.Exit(1) } - } - localSK := cipher.SecKey{} - if *localSKStr != "" { - if err := localSK.UnmarshalText([]byte(*localSKStr)); err != nil { - fmt.Printf("Invalid local SK: %v\n", err) + serverPK := cipher.PubKey{} + if err := serverPK.UnmarshalText([]byte(serverPKStr)); err != nil { + fmt.Printf("Invalid VPN server pub key: %v\n", err) os.Exit(1) } - } - var directIPsCh, nonDirectIPsCh = make(chan net.IP, 100), make(chan net.IP, 100) - defer close(directIPsCh) - defer close(nonDirectIPsCh) - - eventSub := appevent.NewSubscriber() - - parseIP := func(addr string) net.IP { - ip, ok, err := vpn.ParseIP(addr) - if err != nil { - fmt.Printf("Failed to parse IP %s: %v\n", addr, err) - return nil + localPK := cipher.PubKey{} + if localPKStr != "" { + if err := localPK.UnmarshalText([]byte(localPKStr)); err != nil { + fmt.Printf("Invalid local PK: %v\n", err) + os.Exit(1) + } } - if !ok { - fmt.Printf("Failed to parse IP %s\n", addr) - return nil + + localSK := cipher.SecKey{} + if localSKStr != "" { + if err := localSK.UnmarshalText([]byte(localSKStr)); err != nil { + fmt.Printf("Invalid local SK: %v\n", err) + os.Exit(1) + } } - return ip - } + var directIPsCh, nonDirectIPsCh = make(chan net.IP, 100), make(chan net.IP, 100) + defer close(directIPsCh) + defer close(nonDirectIPsCh) - eventSub.OnTCPDial(func(data appevent.TCPDialData) { - if ip := parseIP(data.RemoteAddr); ip != nil { - directIPsCh <- ip - } - }) + eventSub := appevent.NewSubscriber() - eventSub.OnTCPClose(func(data appevent.TCPCloseData) { - if ip := parseIP(data.RemoteAddr); ip != nil { - nonDirectIPsCh <- ip + parseIP := func(addr string) net.IP { + ip, ok, err := vpn.ParseIP(addr) + if err != nil { + fmt.Printf("Failed to parse IP %s: %v\n", addr, err) + return nil + } + if !ok { + fmt.Printf("Failed to parse IP %s\n", addr) + return nil + } + + return ip } - }) - appClient := app.NewClient(eventSub) - defer appClient.Close() + eventSub.OnTCPDial(func(data appevent.TCPDialData) { + if ip := parseIP(data.RemoteAddr); ip != nil { + directIPsCh <- ip + } + }) - fmt.Printf("Connecting to VPN server %s\n", serverPK.String()) + eventSub.OnTCPClose(func(data appevent.TCPCloseData) { + if ip := parseIP(data.RemoteAddr); ip != nil { + nonDirectIPsCh <- ip + } + }) - vpnClientCfg := vpn.ClientConfig{ - Passcode: *passcode, - Killswitch: *killswitch, - ServerPK: serverPK, - } + appClient := app.NewClient(eventSub) + defer appClient.Close() - vpnClient, err := vpn.NewClient(vpnClientCfg, appClient) - if err != nil { - fmt.Printf("Error creating VPN client: %v\n", err) - } + fmt.Printf("Connecting to VPN server %s\n", serverPK.String()) - var directRoutesDone bool - for !directRoutesDone { - select { - case ip := <-directIPsCh: - if err := vpnClient.AddDirectRoute(ip); err != nil { - fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) - } - default: - directRoutesDone = true + vpnClientCfg := vpn.ClientConfig{ + Passcode: passcode, + Killswitch: killswitch, + ServerPK: serverPK, } - } - go func() { - for ip := range directIPsCh { - if err := vpnClient.AddDirectRoute(ip); err != nil { - fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) - } + vpnClient, err := vpn.NewClient(vpnClientCfg, appClient) + if err != nil { + fmt.Printf("Error creating VPN client: %v\n", err) } - }() - go func() { - for ip := range nonDirectIPsCh { - if err := vpnClient.RemoveDirectRoute(ip); err != nil { - fmt.Printf("Failed to remove direct route to %s: %v\n", ip.String(), err) + var directRoutesDone bool + for !directRoutesDone { + select { + case ip := <-directIPsCh: + if err := vpnClient.AddDirectRoute(ip); err != nil { + fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) + } + default: + directRoutesDone = true } } - }() - if runtime.GOOS != "windows" { - osSigs := make(chan os.Signal, 2) - sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} - for _, sig := range sigs { - signal.Notify(osSigs, sig) - } + go func() { + for ip := range directIPsCh { + if err := vpnClient.AddDirectRoute(ip); err != nil { + fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) + } + } + }() go func() { - <-osSigs - vpnClient.Close() + for ip := range nonDirectIPsCh { + if err := vpnClient.RemoveDirectRoute(ip); err != nil { + fmt.Printf("Failed to remove direct route to %s: %v\n", ip.String(), err) + } + } }() - } else { - ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) - if err != nil { - fmt.Printf("Error creating ipc server for VPN client: %v\n", err) - os.Exit(1) + + if runtime.GOOS != "windows" { + osSigs := make(chan os.Signal, 2) + sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} + for _, sig := range sigs { + signal.Notify(osSigs, sig) + } + + go func() { + <-osSigs + vpnClient.Close() + }() + } else { + ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) + if err != nil { + fmt.Printf("Error creating ipc server for VPN client: %v\n", err) + os.Exit(1) + } + go vpnClient.ListenIPC(ipcClient) } - go vpnClient.ListenIPC(ipcClient) - } - if err := vpnClient.Serve(); err != nil { - fmt.Printf("Failed to serve VPN: %v\n", err) + if err := vpnClient.Serve(); err != nil { + fmt.Printf("Failed to serve VPN: %v\n", err) + } + + }, +} + +// Execute executes root CLI command. +func Execute() { + cc.Init(&cc.Config{ + RootCmd: rootCmd, + Headings: cc.HiBlue + cc.Bold, + Commands: cc.HiBlue + cc.Bold, + CmdShortDescr: cc.HiBlue, + Example: cc.HiBlue + cc.Italic, + ExecName: cc.HiBlue + cc.Bold, + Flags: cc.HiBlue + cc.Bold, + FlagsDescr: cc.HiBlue, + NoExtraNewlines: true, + NoBottomNewline: true, + }) + + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) } } + +func main() { + Execute() +} diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index 54066cffe..8fb4fd386 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -1,13 +1,16 @@ package main import ( - "flag" + "fmt" "os" "os/signal" + "os/user" "runtime" "syscall" + cc "github.com/ivanpirog/coloredcobra" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire/internal/vpn" @@ -27,77 +30,125 @@ var ( ) var ( - localPKStr = flag.String("pk", "", "Local PubKey") - localSKStr = flag.String("sk", "", "Local SecKey") - passcode = flag.String("passcode", "", "Passcode to authenticate connecting users") - secure = flag.Bool("secure", true, "Forbid connections from clients to server local network") + localPKStr string + localSKStr string + passcode string + secure bool ) -func main() { - if runtime.GOOS != "linux" { - log.Fatalln("OS is not supported") +func init() { + if runtime.GOOS == "windows" { + fmt.Println("OS is not supported") + os.Exit(1) + } + thisUser, err := user.Current() + if err != nil { + panic(err) } + if (thisUser.Username != "root") && ((skyenv.OS == "linux") || (skyenv.OS == "mac")) { + fmt.Println("vpn server must be run as root") + os.Exit(1) + } + + rootCmd.Flags().SortFlags = false - flag.Parse() + rootCmd.Flags().StringVarP(&localPKStr, "pk", "p", "", "Local PubKey") + rootCmd.Flags().StringVarP(&localSKStr, "sk", "s", "", "Local SecKey") + rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") + rootCmd.Flags().BoolVarP(&secure, "secure", "k", true, "Forbid connections from clients to server local network") +} - localPK := cipher.PubKey{} - if *localPKStr != "" { - if err := localPK.UnmarshalText([]byte(*localPKStr)); err != nil { - log.WithError(err).Fatalln("Invalid local PK") +var rootCmd = &cobra.Command{ + Use: "vpn-server", + Short: "Skywire VPN Server", + Long: ` + ┬ ┬┌─┐┌┐┌ ┌─┐┌─┐┬─┐┬ ┬┌─┐┬─┐ + └┐┌┘├─┘│││───└─┐├┤ ├┬┘└┐┌┘├┤ ├┬┘ + └┘ ┴ ┘└┘ └─┘└─┘┴└─ └┘ └─┘┴└─`, + Run: func(_ *cobra.Command, _ []string) { + localPK := cipher.PubKey{} + if localPKStr != "" { + if err := localPK.UnmarshalText([]byte(localPKStr)); err != nil { + log.WithError(err).Fatalln("Invalid local PK") + } } - } - localSK := cipher.SecKey{} - if *localSKStr != "" { - if err := localSK.UnmarshalText([]byte(*localSKStr)); err != nil { - log.WithError(err).Fatalln("Invalid local SK") + localSK := cipher.SecKey{} + if localSKStr != "" { + if err := localSK.UnmarshalText([]byte(localSKStr)); err != nil { + log.WithError(err).Fatalln("Invalid local SK") + } } - } - appClient := app.NewClient(nil) - defer appClient.Close() + appClient := app.NewClient(nil) + defer appClient.Close() - osSigs := make(chan os.Signal, 2) + osSigs := make(chan os.Signal, 2) - sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} - for _, sig := range sigs { - signal.Notify(osSigs, sig) - } + sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} + for _, sig := range sigs { + signal.Notify(osSigs, sig) + } - l, err := appClient.Listen(netType, vpnPort) - if err != nil { - log.WithError(err).Errorf("Error listening network %v on port %d", netType, vpnPort) - return - } + l, err := appClient.Listen(netType, vpnPort) + if err != nil { + log.WithError(err).Errorf("Error listening network %v on port %d", netType, vpnPort) + return + } - log.Infof("Got app listener, bound to %d", vpnPort) + log.Infof("Got app listener, bound to %d", vpnPort) - srvCfg := vpn.ServerConfig{ - Passcode: *passcode, - Secure: *secure, - } - srv, err := vpn.NewServer(srvCfg, log) - if err != nil { - log.WithError(err).Fatalln("Error creating VPN server") - } - defer func() { - if err := srv.Close(); err != nil { - log.WithError(err).Errorln("Error closing server") + srvCfg := vpn.ServerConfig{ + Passcode: passcode, + Secure: secure, } - }() - - errCh := make(chan error) - go func() { - if err := srv.Serve(l); err != nil { - errCh <- err + srv, err := vpn.NewServer(srvCfg, log) + if err != nil { + log.WithError(err).Fatalln("Error creating VPN server") } + defer func() { + if err := srv.Close(); err != nil { + log.WithError(err).Errorln("Error closing server") + } + }() + + errCh := make(chan error) + go func() { + if err := srv.Serve(l); err != nil { + errCh <- err + } + + close(errCh) + }() + + select { + case <-osSigs: + case err := <-errCh: + log.WithError(err).Errorln("Error serving") + } + }, +} - close(errCh) - }() - - select { - case <-osSigs: - case err := <-errCh: - log.WithError(err).Errorln("Error serving") +// Execute executes root CLI command. +func Execute() { + cc.Init(&cc.Config{ + RootCmd: rootCmd, + Headings: cc.HiBlue + cc.Bold, + Commands: cc.HiBlue + cc.Bold, + CmdShortDescr: cc.HiBlue, + Example: cc.HiBlue + cc.Italic, + ExecName: cc.HiBlue + cc.Bold, + Flags: cc.HiBlue + cc.Bold, + FlagsDescr: cc.HiBlue, + NoExtraNewlines: true, + NoBottomNewline: true, + }) + + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) } } + +func main() { + Execute() +} From cc62436dd529856df4a5c16fc0a906f1d7eb541a Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Tue, 12 Apr 2022 14:11:11 -0500 Subject: [PATCH 06/19] disable browser-launching systray buttons as root ; disable apps that are not found at path specified in config during config gen with small exceptions --- cmd/apps/skychat/skychat.go | 4 +- cmd/apps/skysocks-client/skysocks-client.go | 4 +- cmd/apps/vpn-client/vpn-client.go | 11 ---- cmd/apps/vpn-server/vpn-server.go | 14 ----- cmd/skywire-cli/commands/config/gen.go | 40 +++++++++++++ cmd/skywire-visor/commands/root.go | 7 ++- cmd/skywire-visor/commands/systray.go | 4 +- cmd/skywire-visor/commands/systray_linux.go | 59 ------------------- internal/gui/gui.go | 65 ++++++++++++++++----- internal/gui/gui_unix.go | 16 ++++- local/.gitignore | 4 -- scripts/_apps/skychat | 2 +- 12 files changed, 120 insertions(+), 110 deletions(-) delete mode 100644 cmd/skywire-visor/commands/systray_linux.go delete mode 100644 local/.gitignore diff --git a/cmd/apps/skychat/skychat.go b/cmd/apps/skychat/skychat.go index 05a7a83a1..7986c5ca8 100644 --- a/cmd/apps/skychat/skychat.go +++ b/cmd/apps/skychat/skychat.go @@ -54,8 +54,8 @@ func init() { } var rootCmd = &cobra.Command{ - Use: "skysocks", - Short: "Skywire SOCKS5 Proxy Server", + Use: "skychat", + Short: "Skywire P2P Message Application", Long: ` ┌─┐┬┌─┬ ┬┌─┐┬ ┬┌─┐┌┬┐ └─┐├┴┐└┬┘│ ├─┤├─┤ │ diff --git a/cmd/apps/skysocks-client/skysocks-client.go b/cmd/apps/skysocks-client/skysocks-client.go index 5d8f1dbc8..efb4f9af1 100644 --- a/cmd/apps/skysocks-client/skysocks-client.go +++ b/cmd/apps/skysocks-client/skysocks-client.go @@ -45,8 +45,8 @@ func init() { } var rootCmd = &cobra.Command{ - Use: "skysocks", - Short: "Skywire SOCKS5 Proxy Server", + Use: "skysocks-client", + Short: "Skywire SOCKS5 Proxy Client", Long: ` ┌─┐┬┌─┬ ┬┌─┐┌─┐┌─┐┬┌─┌─┐ ┌─┐┬ ┬┌─┐┌┐┌┌┬┐ └─┐├┴┐└┬┘└─┐│ ││ ├┴┐└─┐───│ │ │├┤ │││ │ diff --git a/cmd/apps/vpn-client/vpn-client.go b/cmd/apps/vpn-client/vpn-client.go index 646308dd4..5c508290c 100644 --- a/cmd/apps/vpn-client/vpn-client.go +++ b/cmd/apps/vpn-client/vpn-client.go @@ -5,7 +5,6 @@ import ( "net" "os" "os/signal" - "os/user" "runtime" "syscall" @@ -29,15 +28,6 @@ var ( ) func init() { - thisUser, err := user.Current() - if err != nil { - panic(err) - } - if (thisUser.Username != "root") && ((skyenv.OS == "linux") || (skyenv.OS == "mac")) { - fmt.Println("vpn client must be run as root") - os.Exit(1) - } - rootCmd.Flags().SortFlags = false rootCmd.Flags().StringVarP(&serverPKStr, "srv", "q", "", "PubKey of the server to connect to") @@ -45,7 +35,6 @@ func init() { rootCmd.Flags().StringVarP(&localSKStr, "sk", "s", "", "Local SecKey") rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") rootCmd.Flags().BoolVarP(&killswitch, "killswitch", "k", false, "If set, the Internet won't be restored during reconnection attempts") - } var rootCmd = &cobra.Command{ diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index 8fb4fd386..8d77da4b6 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "os/signal" - "os/user" "runtime" "syscall" @@ -37,19 +36,6 @@ var ( ) func init() { - if runtime.GOOS == "windows" { - fmt.Println("OS is not supported") - os.Exit(1) - } - thisUser, err := user.Current() - if err != nil { - panic(err) - } - if (thisUser.Username != "root") && ((skyenv.OS == "linux") || (skyenv.OS == "mac")) { - fmt.Println("vpn server must be run as root") - os.Exit(1) - } - rootCmd.Flags().SortFlags = false rootCmd.Flags().StringVarP(&localPKStr, "pk", "p", "", "Local PubKey") diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index ea5c98da2..1589c0ecf 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -236,6 +236,46 @@ var genConfigCmd = &cobra.Command{ } } } + skywire := os.Args[0] + match := strings.Contains("/tmp/", skywire) + if (!stdout) || (!match) { + // Disable apps not found at bin_path with above exceptions for go run and stdout + if _, err := os.Stat(conf.Launcher.BinPath + "skychat"); err != nil { + if disableApps == "" { + disableApps = "skychat" + } else { + disableApps = disableApps + ",skychat" + } + } + if _, err := os.Stat(conf.Launcher.BinPath + "skysocks"); err != nil { + if disableApps == "" { + disableApps = "skysocks" + } else { + disableApps = disableApps + ",skysocks" + } + } + if _, err := os.Stat(conf.Launcher.BinPath + "skysocks-client"); err != nil { + if disableApps == "" { + disableApps = "skysocks-client" + } else { + disableApps = disableApps + ",skysocks-client" + } + } + if _, err := os.Stat(conf.Launcher.BinPath + "vpn-client"); err != nil { + if disableApps == "" { + disableApps = "vpn-client" + } else { + disableApps = disableApps + ",vpn-client" + } + } + if _, err := os.Stat(conf.Launcher.BinPath + "vpn-server"); err != nil { + if disableApps == "" { + disableApps = "vpn-server" + } else { + disableApps = disableApps + ",vpn-server" + } + } + } // Disable apps listed on --disable-apps flag if disableApps != "" { apps := strings.Split(disableApps, ",") diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 46e2b8361..16d4d425b 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -14,6 +14,7 @@ import ( "os/exec" "os/user" "path/filepath" + "regexp" "strings" "sync" "time" @@ -235,7 +236,11 @@ var rootCmd = &cobra.Command{ fork = strings.ReplaceAll(fork, "github.com/", "") fork = strings.ReplaceAll(fork, ":/", "") fork = strings.ReplaceAll(fork, "\n", "") - if nofork := strings.Contains(fork, "skycoin/skywire"); err == nil { + nofork, err := regexp.MatchString("skycoin/skywire", fork) + if err != nil { + log.Error(err) + } else { + log.Info(nofork) if !nofork { fork = "" } diff --git a/cmd/skywire-visor/commands/systray.go b/cmd/skywire-visor/commands/systray.go index 95dc0e677..5acf3a9db 100644 --- a/cmd/skywire-visor/commands/systray.go +++ b/cmd/skywire-visor/commands/systray.go @@ -1,5 +1,5 @@ -//go:build systray && !linux -// +build systray,!linux +//go:build systray +// +build systray package commands diff --git a/cmd/skywire-visor/commands/systray_linux.go b/cmd/skywire-visor/commands/systray_linux.go deleted file mode 100644 index 4ebf4d8b6..000000000 --- a/cmd/skywire-visor/commands/systray_linux.go +++ /dev/null @@ -1,59 +0,0 @@ -//go:build systray && linux -// +build systray,linux - -package commands - -import ( - "context" - - "github.com/getlantern/systray" - "github.com/skycoin/skycoin/src/util/logging" - - "github.com/skycoin/skywire/internal/gui" -) - -func runApp(args ...string) { - //systray app cannot launch browser as root - if root { - runVisor(nil) - } else { - l := logging.NewMasterLogger() - sysTrayIcon, err := gui.ReadSysTrayIcon() - if err != nil { - l.WithError(err).Fatalln("Failed to read system tray icon") - } - conf := initConfig(l, confPath) - go func() { - runVisor(conf) - systray.Quit() - }() - systray.Run(gui.GetOnGUIReady(sysTrayIcon, conf), gui.OnGUIQuit) - } -} - -func setStopFunction(log *logging.MasterLogger, cancel context.CancelFunc, fn func() error) { - stopVisorWg.Add(1) - defer stopVisorWg.Done() - - stopVisorFn = func() { - if err := fn(); err != nil { - log.WithError(err).Error("Visor closed with error.") - } - cancel() - stopVisorWg.Wait() - } - - //systray app cannot launch browser as root - if root { - gui.SetStopVisorFn(func() { - stopVisorFn() - }) - } - -} - -func quitSystray() { - if root { - systray.Quit() - } -} diff --git a/internal/gui/gui.go b/internal/gui/gui.go index 99b2f2d4d..e228131ad 100644 --- a/internal/gui/gui.go +++ b/internal/gui/gui.go @@ -64,24 +64,36 @@ var ( ) // GetOnGUIReady creates func to run on GUI startup. -func GetOnGUIReady(icon []byte, conf *visorconfig.V1) func() { +func GetOnGUIReady(icon []byte, conf *visorconfig.V1) (ret func()) { doneCh := make(chan bool, 1) logger := logging.NewMasterLogger() logger.SetLevel(logrus.InfoLevel) httpC := getHTTPClient(conf, context.Background(), logger) - return func() { - systray.SetTemplateIcon(icon, icon) - systray.SetTooltip("Skywire") - - initOpenVPNLinkBtn(conf) - initAdvancedButton(conf) - initVpnClientBtn(conf, httpC, logger) - initQuitBtn() - - go handleUserInteraction(conf, doneCh) + if checkRoot() { + ret = func() { + systray.SetTemplateIcon(icon, icon) + systray.SetTooltip("Skywire") + initOpenVPNLinkBtn(conf) + initAdvancedButton(conf) + initVpnClientBtn(conf, httpC, logger) + initQuitBtn() + go handleRootInteraction(conf, doneCh) + } } + if !checkRoot() { + ret = func() { + systray.SetTemplateIcon(icon, icon) + systray.SetTooltip("Skywire") + initOpenVPNLinkBtn(conf) + initAdvancedButton(conf) + initVpnClientBtn(conf, httpC, logger) + initQuitBtn() + go handleUserInteraction(conf, doneCh) + } + } + return ret } // OnGUIQuit is executed on GUI exit. @@ -116,6 +128,7 @@ func Stop() { } func initAdvancedButton(conf *visorconfig.V1) { + hvAddr := getHVAddr(conf) mAdvancedButton = systray.AddMenuItem("Advanced", "Advanced Menu") @@ -124,7 +137,12 @@ func initAdvancedButton(conf *visorconfig.V1) { // if it's not installed via package, hide the uninstall button initUninstallBtn() - + //hide the buttons which could launch the browser if the process is run as root + if checkRoot() { + mAdvancedButton.Hide() + mOpenHypervisor.Hide() + return + } // if visor's not running or hypervisor config is absent, // there won't be any way to open the hypervisor, so disable button if hvAddr == "" { @@ -160,7 +178,10 @@ func initAdvancedButton(conf *visorconfig.V1) { func initOpenVPNLinkBtn(vc *visorconfig.V1) { mVPNLink = systray.AddMenuItem("Open VPN UI", "Open VPN UI in browser") - + if checkRoot() { + mVPNLink.Hide() + return + } mVPNLink.Disable() // wait for the vpn client to start in the background @@ -417,6 +438,24 @@ func handleUserInteraction(conf *visorconfig.V1, doneCh chan<- bool) { } } +func handleRootInteraction(conf *visorconfig.V1, doneCh chan<- bool) { + for { + select { +// case <-mOpenHypervisor.ClickedCh: +// handleOpenHypervisor(conf) + case <-mVPNButton.ClickedCh: + handleVPNButton(conf, rpcC) +// case <-mVPNLink.ClickedCh: +// handleVPNLinkButton(conf) + case <-mUninstall.ClickedCh: + handleUninstall() + case <-mQuit.ClickedCh: + doneCh <- true + Stop() + } + } +} + func handleOpenHypervisor(conf *visorconfig.V1) { if err := openHypervisor(conf); err != nil { log.WithError(err).Errorln("Failed to open hypervisor") diff --git a/internal/gui/gui_unix.go b/internal/gui/gui_unix.go index 1e00cc999..ff48811ed 100644 --- a/internal/gui/gui_unix.go +++ b/internal/gui/gui_unix.go @@ -3,8 +3,22 @@ package gui -import "github.com/skycoin/skywire/pkg/util/osutil" +import ( + "os/user" + "github.com/skycoin/skywire/pkg/util/osutil" +) func platformExecUninstall() error { return osutil.Run("/bin/bash", "-c", deinstallerPath) } + +func checkRoot() bool { +thisUser, err := user.Current() +if err != nil { + panic(err) +} +if thisUser.Username == "root" { + return true +} +return false +} diff --git a/local/.gitignore b/local/.gitignore deleted file mode 100644 index 5e7d2734c..000000000 --- a/local/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/scripts/_apps/skychat b/scripts/_apps/skychat index fdf50661b..ba846709d 100755 --- a/scripts/_apps/skychat +++ b/scripts/_apps/skychat @@ -1,2 +1,2 @@ #!/bin/bash -go run ../../cmd/apps/skychat/chat.go +go run ../../cmd/apps/skychat/skychat.go From 6fce3d7d7e4539f656b0995897dddce97e2a998a Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Tue, 12 Apr 2022 14:12:41 -0500 Subject: [PATCH 07/19] disable browser-launching systray buttons as root ; disable apps that are not found at path specified in config during config gen with small exceptions --- cmd/apps/vpn-server/vpn-server.go | 1 - cmd/skywire-cli/commands/config/gen.go | 62 +++++++++++++------------- internal/gui/gui.go | 8 ++-- internal/gui/gui_unix.go | 19 ++++---- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index 8d77da4b6..6923f4e2c 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "os/signal" - "runtime" "syscall" cc "github.com/ivanpirog/coloredcobra" diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 1589c0ecf..8f527906b 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -239,43 +239,43 @@ var genConfigCmd = &cobra.Command{ skywire := os.Args[0] match := strings.Contains("/tmp/", skywire) if (!stdout) || (!match) { - // Disable apps not found at bin_path with above exceptions for go run and stdout - if _, err := os.Stat(conf.Launcher.BinPath + "skychat"); err != nil { - if disableApps == "" { - disableApps = "skychat" - } else { - disableApps = disableApps + ",skychat" + // Disable apps not found at bin_path with above exceptions for go run and stdout + if _, err := os.Stat(conf.Launcher.BinPath + "skychat"); err != nil { + if disableApps == "" { + disableApps = "skychat" + } else { + disableApps = disableApps + ",skychat" + } } - } - if _, err := os.Stat(conf.Launcher.BinPath + "skysocks"); err != nil { - if disableApps == "" { - disableApps = "skysocks" - } else { - disableApps = disableApps + ",skysocks" + if _, err := os.Stat(conf.Launcher.BinPath + "skysocks"); err != nil { + if disableApps == "" { + disableApps = "skysocks" + } else { + disableApps = disableApps + ",skysocks" + } } - } - if _, err := os.Stat(conf.Launcher.BinPath + "skysocks-client"); err != nil { - if disableApps == "" { - disableApps = "skysocks-client" - } else { - disableApps = disableApps + ",skysocks-client" + if _, err := os.Stat(conf.Launcher.BinPath + "skysocks-client"); err != nil { + if disableApps == "" { + disableApps = "skysocks-client" + } else { + disableApps = disableApps + ",skysocks-client" + } } - } - if _, err := os.Stat(conf.Launcher.BinPath + "vpn-client"); err != nil { - if disableApps == "" { - disableApps = "vpn-client" - } else { - disableApps = disableApps + ",vpn-client" + if _, err := os.Stat(conf.Launcher.BinPath + "vpn-client"); err != nil { + if disableApps == "" { + disableApps = "vpn-client" + } else { + disableApps = disableApps + ",vpn-client" + } } - } - if _, err := os.Stat(conf.Launcher.BinPath + "vpn-server"); err != nil { - if disableApps == "" { - disableApps = "vpn-server" - } else { - disableApps = disableApps + ",vpn-server" + if _, err := os.Stat(conf.Launcher.BinPath + "vpn-server"); err != nil { + if disableApps == "" { + disableApps = "vpn-server" + } else { + disableApps = disableApps + ",vpn-server" + } } } - } // Disable apps listed on --disable-apps flag if disableApps != "" { apps := strings.Split(disableApps, ",") diff --git a/internal/gui/gui.go b/internal/gui/gui.go index e228131ad..5a9091ae1 100644 --- a/internal/gui/gui.go +++ b/internal/gui/gui.go @@ -441,12 +441,12 @@ func handleUserInteraction(conf *visorconfig.V1, doneCh chan<- bool) { func handleRootInteraction(conf *visorconfig.V1, doneCh chan<- bool) { for { select { -// case <-mOpenHypervisor.ClickedCh: -// handleOpenHypervisor(conf) + // case <-mOpenHypervisor.ClickedCh: + // handleOpenHypervisor(conf) case <-mVPNButton.ClickedCh: handleVPNButton(conf, rpcC) -// case <-mVPNLink.ClickedCh: -// handleVPNLinkButton(conf) + // case <-mVPNLink.ClickedCh: + // handleVPNLinkButton(conf) case <-mUninstall.ClickedCh: handleUninstall() case <-mQuit.ClickedCh: diff --git a/internal/gui/gui_unix.go b/internal/gui/gui_unix.go index ff48811ed..f2e110baf 100644 --- a/internal/gui/gui_unix.go +++ b/internal/gui/gui_unix.go @@ -6,19 +6,20 @@ package gui import ( "os/user" - "github.com/skycoin/skywire/pkg/util/osutil" + "github.com/skycoin/skywire/pkg/util/osutil" ) + func platformExecUninstall() error { return osutil.Run("/bin/bash", "-c", deinstallerPath) } func checkRoot() bool { -thisUser, err := user.Current() -if err != nil { - panic(err) -} -if thisUser.Username == "root" { - return true -} -return false + thisUser, err := user.Current() + if err != nil { + panic(err) + } + if thisUser.Username == "root" { + return true + } + return false } From cf7778ab692eda740a4bade9b20a2dc15fd1a9bb Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Tue, 12 Apr 2022 14:30:40 -0500 Subject: [PATCH 08/19] fix app autodisable in config gen --- cmd/skywire-cli/commands/config/gen.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 8f527906b..53b59186f 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -240,35 +240,35 @@ var genConfigCmd = &cobra.Command{ match := strings.Contains("/tmp/", skywire) if (!stdout) || (!match) { // Disable apps not found at bin_path with above exceptions for go run and stdout - if _, err := os.Stat(conf.Launcher.BinPath + "skychat"); err != nil { + if _, err := os.Stat(conf.Launcher.BinPath + "/" + "skychat"); err != nil { if disableApps == "" { disableApps = "skychat" } else { disableApps = disableApps + ",skychat" } } - if _, err := os.Stat(conf.Launcher.BinPath + "skysocks"); err != nil { + if _, err := os.Stat(conf.Launcher.BinPath + "/" + "skysocks"); err != nil { if disableApps == "" { disableApps = "skysocks" } else { disableApps = disableApps + ",skysocks" } } - if _, err := os.Stat(conf.Launcher.BinPath + "skysocks-client"); err != nil { + if _, err := os.Stat(conf.Launcher.BinPath + "/" + "skysocks-client"); err != nil { if disableApps == "" { disableApps = "skysocks-client" } else { disableApps = disableApps + ",skysocks-client" } } - if _, err := os.Stat(conf.Launcher.BinPath + "vpn-client"); err != nil { + if _, err := os.Stat(conf.Launcher.BinPath + "/" + "vpn-client"); err != nil { if disableApps == "" { disableApps = "vpn-client" } else { disableApps = disableApps + ",vpn-client" } } - if _, err := os.Stat(conf.Launcher.BinPath + "vpn-server"); err != nil { + if _, err := os.Stat(conf.Launcher.BinPath + "/" + "vpn-server"); err != nil { if disableApps == "" { disableApps = "vpn-server" } else { From 4d863444475e7b769fc3a18b5aac032b7db73f86 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Tue, 12 Apr 2022 22:59:34 -0500 Subject: [PATCH 09/19] fail on incorrect or insufficient write permissions - prevent writing as root to non root-owned path and fail before attempted non-root write to root-owned path for skywire-cli config gen and skywire-visor --- cmd/skywire-cli/commands/config/gen.go | 37 +++++++++++++++++++++++--- cmd/skywire-visor/commands/root.go | 15 +++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 53b59186f..7719c9498 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -4,9 +4,12 @@ import ( "encoding/json" "fmt" "os" + "os/exec" + "os/user" "path/filepath" "strings" + "github.com/bitfield/script" "github.com/sirupsen/logrus" "github.com/skycoin/skycoin/src/util/logging" "github.com/spf13/cobra" @@ -47,6 +50,7 @@ var ( all bool outunset bool ver string + root bool svcconf = strings.ReplaceAll(utilenv.ServiceConfAddr, "http://", "") //skyenv.DefaultServiceConfAddr testconf = strings.ReplaceAll(utilenv.TestServiceConfAddr, "http://", "") //skyenv.DefaultServiceConfAddr hiddenflags []string @@ -76,7 +80,7 @@ func init() { hiddenflags = append(hiddenflags, "os") genConfigCmd.Flags().BoolVarP(&stdout, "stdout", "n", false, "write config to stdout") hiddenflags = append(hiddenflags, "stdout") - genConfigCmd.Flags().StringVarP(&output, "out", "o", skyenv.ConfigName, "output config") + genConfigCmd.Flags().StringVarP(&output, "out", "o", "", "output config: "+skyenv.ConfigName) genConfigCmd.Flags().BoolVarP(&pkgEnv, "package", "p", false, "use paths for package "+skyenv.SkywirePath) genConfigCmd.Flags().BoolVarP(&publicRPC, "publicrpc", "q", false, "allow rpc requests from LAN") hiddenflags = append(hiddenflags, "publicrpc") @@ -196,7 +200,6 @@ var genConfigCmd = &cobra.Command{ } confPath = skyenv.SkywirePath + "/" + configName } - // Read in old config and obtain old secret key or generate a new random secret key // and obtain old hypervisors (if any) var sk cipher.SecKey @@ -306,7 +309,7 @@ var genConfigCmd = &cobra.Command{ } } // Check OS and enable auth windows or macos - if selectedOS == "windows" || selectedOS == "macos" { + if (selectedOS == "windows") || (selectedOS == "macos") { if hypervisor { conf.Hypervisor.EnableAuth = true } @@ -316,7 +319,33 @@ var genConfigCmd = &cobra.Command{ } //don't write file with stdout if !stdout { - // Save config to file. + thisUser, err := user.Current() + if err != nil { + panic(err) + } + if thisUser.Username == "root" { + root = true + } + //dont write config as root to non root owned dir & vice versa + if _, err = exec.LookPath("stat"); err == nil { + + confPath1, _ := filepath.Split(confPath) + if confPath1 == "" { + confPath1 = "./" + } + owner, err := script.Exec(`stat -c '%U' `+confPath1).String() + if err != nil { + logger.Error("cannot stat: "+confPath1) + } + if ((owner != "root") || (owner != "root\n")) && root { + logger.Fatal("declined writing config as root to directory not owned by root") + } + if !root && ((owner == "root") || (owner == "root\n")) { + logger.Fatal("Insufficient permissions to write to the specified path") + } + } + + // Save config to file. if err := conf.Flush(); err != nil { logger.WithError(err).Fatal("Failed to flush config to file.") } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 16d4d425b..7c41a5309 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -293,6 +293,21 @@ func runVisor(conf *visorconfig.V1) { conf = initConfig(log, confPath) } + //dont create files & directories as root in non root-owned dir + if _, err := exec.LookPath("stat"); err == nil { + if owner, err := script.Exec(`stat -c '%U' ` + conf.LocalPath + "/..").String(); err == nil { + if (((owner != "root") || (owner != "root\n")) && root) { + log.WithField("local path: ", conf.LocalPath).Error() + log.Fatal("not writing as root to local path not owned by root") + } + //similarly, anticipate and fail on the reverse instance + if (((owner == "root") || (owner == "root\n")) && !root) { + log.WithField("local path: ", conf.LocalPath).Error() + log.Fatal("Insufficient permissions to write to the local path") + } + } + } + if disableHypervisorPKs { conf.Hypervisors = []cipher.PubKey{} } From 6a1a4a7dd1ad5ff9bba477d06293fc85c7adf904 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Tue, 12 Apr 2022 23:00:57 -0500 Subject: [PATCH 10/19] fail on incorrect or insufficient write permissions - prevent writing as root to non root-owned path and fail before attempted non-root write to root-owned path for skywire-cli config gen and skywire-visor --- cmd/skywire-cli/commands/config/gen.go | 32 +++++++++++++------------- cmd/skywire-visor/commands/root.go | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 7719c9498..65f2ee7d7 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -50,7 +50,7 @@ var ( all bool outunset bool ver string - root bool + root bool svcconf = strings.ReplaceAll(utilenv.ServiceConfAddr, "http://", "") //skyenv.DefaultServiceConfAddr testconf = strings.ReplaceAll(utilenv.TestServiceConfAddr, "http://", "") //skyenv.DefaultServiceConfAddr hiddenflags []string @@ -330,22 +330,22 @@ var genConfigCmd = &cobra.Command{ if _, err = exec.LookPath("stat"); err == nil { confPath1, _ := filepath.Split(confPath) - if confPath1 == "" { - confPath1 = "./" - } - owner, err := script.Exec(`stat -c '%U' `+confPath1).String() - if err != nil { - logger.Error("cannot stat: "+confPath1) - } - if ((owner != "root") || (owner != "root\n")) && root { - logger.Fatal("declined writing config as root to directory not owned by root") - } - if !root && ((owner == "root") || (owner == "root\n")) { - logger.Fatal("Insufficient permissions to write to the specified path") - } - } + if confPath1 == "" { + confPath1 = "./" + } + owner, err := script.Exec(`stat -c '%U' ` + confPath1).String() + if err != nil { + logger.Error("cannot stat: " + confPath1) + } + if ((owner != "root") || (owner != "root\n")) && root { + logger.Fatal("declined writing config as root to directory not owned by root") + } + if !root && ((owner == "root") || (owner == "root\n")) { + logger.Fatal("Insufficient permissions to write to the specified path") + } + } - // Save config to file. + // Save config to file. if err := conf.Flush(); err != nil { logger.WithError(err).Fatal("Failed to flush config to file.") } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 7c41a5309..8042e3e9d 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -296,12 +296,12 @@ func runVisor(conf *visorconfig.V1) { //dont create files & directories as root in non root-owned dir if _, err := exec.LookPath("stat"); err == nil { if owner, err := script.Exec(`stat -c '%U' ` + conf.LocalPath + "/..").String(); err == nil { - if (((owner != "root") || (owner != "root\n")) && root) { + if ((owner != "root") || (owner != "root\n")) && root { log.WithField("local path: ", conf.LocalPath).Error() log.Fatal("not writing as root to local path not owned by root") } //similarly, anticipate and fail on the reverse instance - if (((owner == "root") || (owner == "root\n")) && !root) { + if ((owner == "root") || (owner == "root\n")) && !root { log.WithField("local path: ", conf.LocalPath).Error() log.Fatal("Insufficient permissions to write to the local path") } From 6b5fab81b85b1af4356bf071c399a76cac62f47b Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 13:20:35 -0500 Subject: [PATCH 11/19] implement -u --user flag for skywire-cli config gen & skywire-visor --- cmd/skywire-cli/commands/config/gen.go | 29 ++++++++++++++++++-------- cmd/skywire-visor/commands/root.go | 22 ++++++++++++------- pkg/skyenv/values.go | 6 ++++++ pkg/skyenv/values_darwin.go | 13 +++++++++--- pkg/skyenv/values_linux.go | 13 ++++++++++-- pkg/skyenv/values_windows.go | 16 ++++++++++---- pkg/visor/visorconfig/config.go | 19 +++++++++++------ 7 files changed, 86 insertions(+), 32 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 65f2ee7d7..ea2d8d063 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -32,6 +32,7 @@ var ( retainHypervisors bool testEnv bool pkgEnv bool + usrEnv bool hypervisor bool hypervisorPKs string dmsgHTTP bool @@ -81,7 +82,8 @@ func init() { genConfigCmd.Flags().BoolVarP(&stdout, "stdout", "n", false, "write config to stdout") hiddenflags = append(hiddenflags, "stdout") genConfigCmd.Flags().StringVarP(&output, "out", "o", "", "output config: "+skyenv.ConfigName) - genConfigCmd.Flags().BoolVarP(&pkgEnv, "package", "p", false, "use paths for package "+skyenv.SkywirePath) + genConfigCmd.Flags().BoolVarP(&pkgEnv, "pkg", "p", false, "use paths for package: "+skyenv.SkywirePath) + genConfigCmd.Flags().BoolVarP(&usrEnv, "user", "u", false, "use paths for user space: "+skyenv.HomePath()) genConfigCmd.Flags().BoolVarP(&publicRPC, "publicrpc", "q", false, "allow rpc requests from LAN") hiddenflags = append(hiddenflags, "publicrpc") genConfigCmd.Flags().BoolVarP(®en, "regen", "r", false, "re-generate existing config & retain keys") @@ -136,6 +138,10 @@ var genConfigCmd = &cobra.Command{ if (force) && (regen) { logger.Fatal("Use of mutually exclusive flags: -f --force cannot override -r --regen") } + //--force will delete a config, which excludes --regen + if (usrEnv) && (pkgEnv) { + logger.Fatal("Use of mutually exclusive flags: -u --user and -p --pkg") + } var err error //hide defeats the purpose of stdout. if (stdout) && (hide) { @@ -191,14 +197,19 @@ var genConfigCmd = &cobra.Command{ //fetch the service endpoints services = visorconfig.Fetch(mLog, serviceConfURL, stdout) // skywire-cli config gen -ip || skywire-cli config gen -p - if !stdout && outunset && pkgEnv && (selectedOS == "linux") { - if hypervisor { - //default config hypervisor - configName = "skywire.json" - } else { - configName = "skywire-visor.json" + if !stdout && outunset && (selectedOS == "linux") { + if pkgEnv { + if hypervisor { + //default config hypervisor + configName = "skywire.json" + } else { + configName = "skywire-visor.json" + } + confPath = skyenv.SkywirePath + "/" + configName + } + if usrEnv { + confPath = skyenv.HomePath() + "/" + skyenv.ConfigName } - confPath = skyenv.SkywirePath + "/" + configName } // Read in old config and obtain old secret key or generate a new random secret key // and obtain old hypervisors (if any) @@ -222,7 +233,7 @@ var genConfigCmd = &cobra.Command{ } //create the conf - conf, err := visorconfig.MakeDefaultConfig(mLog, &sk, pkgEnv, testEnv, dmsgHTTP, hypervisor, output, hypervisorPKs, services) + conf, err := visorconfig.MakeDefaultConfig(mLog, &sk, usrEnv, pkgEnv, testEnv, dmsgHTTP, hypervisor, confPath, hypervisorPKs, services) if err != nil { logger.WithError(err).Fatal("Failed to create config.") } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 8042e3e9d..717201377 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -63,7 +63,7 @@ var ( all bool pkg bool pkg1 bool - + usr bool // skywire is the path to the running visor binary skywire string // workDir is the working directory where skywire-visor was executed @@ -97,10 +97,17 @@ func init() { rootCmd.Flags().BoolVarP(&stdin, "stdin", "n", false, "read config from stdin") hiddenflags = append(hiddenflags, "stdin") if skyenv.OS == "linux" { - rootCmd.Flags().BoolVar(&pkg, "ph", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirejson) - hiddenflags = append(hiddenflags, "ph") - rootCmd.Flags().BoolVar(&pkg1, "pv", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirevisorjson) - hiddenflags = append(hiddenflags, "pv") + if _, err := os.Stat(skyenv.SkywirePath + "/" + skyenv.Skywirejson); err == nil { + rootCmd.Flags().BoolVar(&pkg, "ph", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirejson) + hiddenflags = append(hiddenflags, "ph") + } + if _, err := os.Stat(skyenv.SkywirePath + "/" + skyenv.Skywirevisorjson); err == nil { + rootCmd.Flags().BoolVar(&pkg1, "pv", false, "use package config "+skyenv.SkywirePath+"/"+skyenv.Skywirevisorjson) + hiddenflags = append(hiddenflags, "pv") + } + } + if _, err := os.Stat(skyenv.HomePath() + "/" + skyenv.ConfigName); err == nil { + rootCmd.Flags().BoolVarP(&usr, "user", "u", false, "use config at: "+skyenv.HomePath()+"/"+skyenv.ConfigName) } rootCmd.Flags().StringVarP(&pprofMode, "pprofmode", "p", "", "pprof mode: cpu, mem, mutex, block, trace, http") hiddenflags = append(hiddenflags, "pprofmode") @@ -170,8 +177,8 @@ var rootCmd = &cobra.Command{ _, hook := logstore.MakeStore(runtimeLogMaxEntries) log.AddHook(hook) if !stdin { - //multiple configs from flags - if (pkg && pkg1) || ((pkg || pkg1) && (confPath != "")) { + //error on multiple configs from flags + if (pkg && pkg1) || (pkg && usr) || (pkg1 && usr) || ((pkg || pkg1) && (confPath != "")) { fmt.Println("Error: multiple configs specified") os.Exit(1) } @@ -183,7 +190,6 @@ var rootCmd = &cobra.Command{ if pkg1 { confPath = skyenv.SkywirePath + "/" + skyenv.Skywirevisorjson } - //enforce .json extension if !strings.HasSuffix(confPath, ".json") { //append .json diff --git a/pkg/skyenv/values.go b/pkg/skyenv/values.go index 736cfd0d5..03f1e2ae0 100644 --- a/pkg/skyenv/values.go +++ b/pkg/skyenv/values.go @@ -169,3 +169,9 @@ func Version() string { } return v } + +// HomePath gets the current user's home folder +func HomePath() string { + dir, _ := os.UserHomeDir() //nolint + return dir +} diff --git a/pkg/skyenv/values_darwin.go b/pkg/skyenv/values_darwin.go index 1471532ff..01745ce15 100644 --- a/pkg/skyenv/values_darwin.go +++ b/pkg/skyenv/values_darwin.go @@ -6,13 +6,10 @@ package skyenv const ( //OS detection at runtime OS = "mac" - // SkywirePath is the path to the installation folder. SkywirePath = "/Library/Application Support/Skywire" ) -//TODO implement this similarly for macOS - // PackageConfig contains installation paths (for mac) func PackageConfig() PkgConfig { var pkgconfig PkgConfig @@ -22,3 +19,13 @@ func PackageConfig() PkgConfig { pkgconfig.Hypervisor.EnableAuth = true return pkgconfig } + +// UserConfig contains installation paths (for mac) +func UserConfig() PkgConfig { + var usrconfig PkgConfig + usrconfig.Launcher.BinPath = "/Library/Application Support/Skywire/apps" + usrconfig.LocalPath = HomePath() + "/.skywire/local" + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.EnableAuth = true + return usrconfig +} diff --git a/pkg/skyenv/values_linux.go b/pkg/skyenv/values_linux.go index c3eefcdd5..041d1022a 100644 --- a/pkg/skyenv/values_linux.go +++ b/pkg/skyenv/values_linux.go @@ -6,7 +6,6 @@ package skyenv const ( //OS detection at runtime OS = "linux" - // SkywirePath is the path to the installation folder for the linux packages. SkywirePath = "/opt/skywire" ) @@ -16,7 +15,17 @@ func PackageConfig() PkgConfig { var pkgconfig PkgConfig pkgconfig.Launcher.BinPath = "/opt/skywire/apps" pkgconfig.LocalPath = "/opt/skywire/local" - pkgconfig.Hypervisor.DbPath = "/opt/skywire/users.db" //permissions errors if the process is not run as root. + pkgconfig.Hypervisor.DbPath = "/opt/skywire/users.db" pkgconfig.Hypervisor.EnableAuth = true return pkgconfig } + +// UserConfig contains installation paths (for linux) +func UserConfig() PkgConfig { + var usrconfig PkgConfig + usrconfig.Launcher.BinPath = "/opt/skywire/apps" + usrconfig.LocalPath = HomePath() + "/.skywire/local" + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.EnableAuth = true + return usrconfig +} diff --git a/pkg/skyenv/values_windows.go b/pkg/skyenv/values_windows.go index 8cb4d60a8..08fd29153 100644 --- a/pkg/skyenv/values_windows.go +++ b/pkg/skyenv/values_windows.go @@ -3,15 +3,13 @@ package skyenv -//OS detection at runtime const ( + //OS detection at runtime OS = "win" - // SkywirePath is the path to the installation folder + // SkywirePath is the path to the installation folder for the .msi SkywirePath = "C:/Program Files/Skywire" ) -//TODO implement this similarly for windows - // PackageConfig contains installation paths (for windows) func PackageConfig() PkgConfig { var pkgconfig PkgConfig @@ -21,3 +19,13 @@ func PackageConfig() PkgConfig { pkgconfig.Hypervisor.EnableAuth = true return pkgconfig } + +// UserConfig contains installation paths (for windows) +func UserConfig() PkgConfig { + var usrconfig PkgConfig + usrconfig.Launcher.BinPath = "C:/Program Files/Skywire/apps" + usrconfig.LocalPath = HomePath() + "/.skywire/local" + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.EnableAuth = true + return usrconfig +} diff --git a/pkg/visor/visorconfig/config.go b/pkg/visor/visorconfig/config.go index c2f95e3d7..b8855d218 100644 --- a/pkg/visor/visorconfig/config.go +++ b/pkg/visor/visorconfig/config.go @@ -109,12 +109,14 @@ func MakeBaseConfig(common *Common, testEnv bool, dmsgHTTP bool, services *Servi // The config's 'sk' field will be nil if not specified. // Generated config will be saved to 'confPath'. // This function always returns the latest config version. -func MakeDefaultConfig(log *logging.MasterLogger, sk *cipher.SecKey, pkgEnv bool, testEnv bool, dmsgHTTP bool, hypervisor bool, confPath, hypervisorPKs string, services *Services) (*V1, error) { +func MakeDefaultConfig(log *logging.MasterLogger, sk *cipher.SecKey, usrEnv bool, pkgEnv bool, testEnv bool, dmsgHTTP bool, hypervisor bool, confPath, hypervisorPKs string, services *Services) (*V1, error) { + if usrEnv && pkgEnv { + log.Fatal("usrEnv and pkgEnv are mutually exclusive") + } cc, err := NewCommon(log, confPath, sk) if err != nil { return nil, err } - var dmsgHTTPServersList *DmsgHTTPServers if dmsgHTTP { @@ -155,12 +157,10 @@ func MakeDefaultConfig(log *logging.MasterLogger, sk *cipher.SecKey, pkgEnv bool } } } - if hypervisor { config := hypervisorconfig.GenerateWorkDirConfig(false) conf.Hypervisor = &config } - if pkgEnv { pkgconfig := skyenv.PackageConfig() conf.LocalPath = pkgconfig.LocalPath @@ -170,9 +170,16 @@ func MakeDefaultConfig(log *logging.MasterLogger, sk *cipher.SecKey, pkgEnv bool conf.Hypervisor.DBPath = pkgconfig.Hypervisor.DbPath } } - + if usrEnv { + usrconfig := skyenv.UserConfig() + conf.LocalPath = usrconfig.LocalPath + conf.Launcher.BinPath = usrconfig.Launcher.BinPath + if conf.Hypervisor != nil { + conf.Hypervisor.EnableAuth = usrconfig.Hypervisor.EnableAuth + conf.Hypervisor.DBPath = usrconfig.Hypervisor.DbPath + } + } return conf, nil - } // SetDefaultTestingValues mutates configuration to use testing values From f83f340a430f74c2f6e2ac5c2e3eead38929eac0 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 13:49:02 -0500 Subject: [PATCH 12/19] fix -u flag imlementation for skywire-visor --- cmd/skywire-cli/commands/config/gen.go | 18 ++++-- cmd/skywire-visor/commands/root.go | 3 + r | 90 ++++++++++++++++++++++++++ wr | 90 ++++++++++++++++++++++++++ 4 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 r create mode 100644 wr diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index ea2d8d063..ee1f4b9f9 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -134,19 +134,23 @@ var genConfigCmd = &cobra.Command{ force = false regen = false } + //hide defeats the purpose of stdout. + if (stdout) && (hide) { + logger.Fatal("Use of mutually exclusive flags: -w --hide and -n --stdout") + } //--force will delete a config, which excludes --regen if (force) && (regen) { logger.Fatal("Use of mutually exclusive flags: -f --force cannot override -r --regen") } - //--force will delete a config, which excludes --regen + // these flags overwrite each other if (usrEnv) && (pkgEnv) { logger.Fatal("Use of mutually exclusive flags: -u --user and -p --pkg") } + //enable local hypervisor by default for user + if usrEnv { + hypervisor = true + } var err error - //hide defeats the purpose of stdout. - if (stdout) && (hide) { - logger.Fatal("Use of mutually exclusive flags: -w --hide and -n --stdout") - } if dmsgHTTP { dmsgHTTPPath := skyenv.DMSGHTTPName if pkgEnv { @@ -201,9 +205,9 @@ var genConfigCmd = &cobra.Command{ if pkgEnv { if hypervisor { //default config hypervisor - configName = "skywire.json" + configName = skyenv.Skywirejson } else { - configName = "skywire-visor.json" + configName = skyenv.Skywirevisorjson } confPath = skyenv.SkywirePath + "/" + configName } diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 717201377..7c52afca4 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -190,6 +190,9 @@ var rootCmd = &cobra.Command{ if pkg1 { confPath = skyenv.SkywirePath + "/" + skyenv.Skywirevisorjson } + if usr { + confPath = skyenv.HomePath() + "/" + skyenv.ConfigName + } //enforce .json extension if !strings.HasSuffix(confPath, ".json") { //append .json diff --git a/r b/r new file mode 100644 index 000000000..1575585fe --- /dev/null +++ b/r @@ -0,0 +1,90 @@ +{ + "version": "v0.6.0", + "sk": "a24666d8200f4b80ed711495cacc5bf32616611ae18cdf6c393ef04229cf8a94", + "pk": "03665141c243e6280d50688c4579b1b24c61f81c3ea78aff9435c12f1b8964f77d", + "dmsg": { + "discovery": "http://dmsgd.skywire.skycoin.com", + "sessions_count": 1, + "servers": [] + }, + "dmsgpty": { + "dmsg_port": 22, + "cli_network": "unix", + "cli_address": "/tmp/dmsgpty.sock" + }, + "skywire-tcp": { + "pk_table": null, + "listening_address": ":7777" + }, + "transport": { + "discovery": "http://tpd.skywire.skycoin.com", + "address_resolver": "http://ar.skywire.skycoin.com", + "public_autoconnect": true, + "transport_setup_nodes": null + }, + "routing": { + "setup_nodes": [ + "0324579f003e6b4048bae2def4365e634d8e0e3054a20fc7af49daf2a179658557" + ], + "route_finder": "http://rf.skywire.skycoin.com", + "route_finder_timeout": "10s", + "min_hops": 0 + }, + "uptime_tracker": { + "addr": "http://ut.skywire.skycoin.com" + }, + "launcher": { + "service_discovery": "http://sd.skycoin.com", + "apps": [ + { + "name": "vpn-client", + "auto_start": false, + "port": 43 + }, + { + "name": "skychat", + "args": [ + "-addr", + ":8001" + ], + "auto_start": true, + "port": 1 + }, + { + "name": "skysocks", + "auto_start": true, + "port": 3 + }, + { + "name": "skysocks-client", + "auto_start": false, + "port": 13 + }, + { + "name": "vpn-server", + "auto_start": false, + "port": 44 + } + ], + "server_addr": "localhost:5505", + "bin_path": "/opt/skywire/apps" + }, + "hypervisors": [], + "cli_addr": "localhost:3435", + "log_level": "info", + "local_path": "/opt/skywire/local", + "stun_servers": [ + "172.104.188.139:3478", + "172.104.59.235:3478", + "172.104.183.187:3478", + "139.162.54.63:3478", + "172.105.115.97:3478", + "172.104.188.39:3478", + "172.104.188.140:3478", + "172.104.40.88:3478" + ], + "shutdown_timeout": "10s", + "restart_check_delay": "1s", + "is_public": false, + "persistent_transports": null +} \ No newline at end of file diff --git a/wr b/wr new file mode 100644 index 000000000..126fbadc3 --- /dev/null +++ b/wr @@ -0,0 +1,90 @@ +{ + "version": "v0.6.0", + "sk": "117fc808ead184a500cc0ccc0c23d6bef2838802a799bae92ace0f83f59fd6be", + "pk": "027e223184463b8f44e86bb3d2fbfeb029deacdb08f41e84935883e09dbc77a226", + "dmsg": { + "discovery": "http://dmsgd.skywire.skycoin.com", + "sessions_count": 1, + "servers": [] + }, + "dmsgpty": { + "dmsg_port": 22, + "cli_network": "unix", + "cli_address": "/tmp/dmsgpty.sock" + }, + "skywire-tcp": { + "pk_table": null, + "listening_address": ":7777" + }, + "transport": { + "discovery": "http://tpd.skywire.skycoin.com", + "address_resolver": "http://ar.skywire.skycoin.com", + "public_autoconnect": true, + "transport_setup_nodes": null + }, + "routing": { + "setup_nodes": [ + "0324579f003e6b4048bae2def4365e634d8e0e3054a20fc7af49daf2a179658557" + ], + "route_finder": "http://rf.skywire.skycoin.com", + "route_finder_timeout": "10s", + "min_hops": 0 + }, + "uptime_tracker": { + "addr": "http://ut.skywire.skycoin.com" + }, + "launcher": { + "service_discovery": "http://sd.skycoin.com", + "apps": [ + { + "name": "vpn-client", + "auto_start": false, + "port": 43 + }, + { + "name": "skychat", + "args": [ + "-addr", + ":8001" + ], + "auto_start": true, + "port": 1 + }, + { + "name": "skysocks", + "auto_start": true, + "port": 3 + }, + { + "name": "skysocks-client", + "auto_start": false, + "port": 13 + }, + { + "name": "vpn-server", + "auto_start": false, + "port": 44 + } + ], + "server_addr": "localhost:5505", + "bin_path": "/opt/skywire/apps" + }, + "hypervisors": [], + "cli_addr": "localhost:3435", + "log_level": "info", + "local_path": "/opt/skywire/local", + "stun_servers": [ + "172.104.188.139:3478", + "172.104.59.235:3478", + "172.104.183.187:3478", + "139.162.54.63:3478", + "172.105.115.97:3478", + "172.104.188.39:3478", + "172.104.188.140:3478", + "172.104.40.88:3478" + ], + "shutdown_timeout": "10s", + "restart_check_delay": "1s", + "is_public": false, + "persistent_transports": null +} \ No newline at end of file From 650ccf38609bd5a0c2500b3f1e3f609fb13eb1ce Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 13:49:27 -0500 Subject: [PATCH 13/19] implement -u --user flag for skywire-cli config gen & skywire-visor --- wr | 90 -------------------------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 wr diff --git a/wr b/wr deleted file mode 100644 index 126fbadc3..000000000 --- a/wr +++ /dev/null @@ -1,90 +0,0 @@ -{ - "version": "v0.6.0", - "sk": "117fc808ead184a500cc0ccc0c23d6bef2838802a799bae92ace0f83f59fd6be", - "pk": "027e223184463b8f44e86bb3d2fbfeb029deacdb08f41e84935883e09dbc77a226", - "dmsg": { - "discovery": "http://dmsgd.skywire.skycoin.com", - "sessions_count": 1, - "servers": [] - }, - "dmsgpty": { - "dmsg_port": 22, - "cli_network": "unix", - "cli_address": "/tmp/dmsgpty.sock" - }, - "skywire-tcp": { - "pk_table": null, - "listening_address": ":7777" - }, - "transport": { - "discovery": "http://tpd.skywire.skycoin.com", - "address_resolver": "http://ar.skywire.skycoin.com", - "public_autoconnect": true, - "transport_setup_nodes": null - }, - "routing": { - "setup_nodes": [ - "0324579f003e6b4048bae2def4365e634d8e0e3054a20fc7af49daf2a179658557" - ], - "route_finder": "http://rf.skywire.skycoin.com", - "route_finder_timeout": "10s", - "min_hops": 0 - }, - "uptime_tracker": { - "addr": "http://ut.skywire.skycoin.com" - }, - "launcher": { - "service_discovery": "http://sd.skycoin.com", - "apps": [ - { - "name": "vpn-client", - "auto_start": false, - "port": 43 - }, - { - "name": "skychat", - "args": [ - "-addr", - ":8001" - ], - "auto_start": true, - "port": 1 - }, - { - "name": "skysocks", - "auto_start": true, - "port": 3 - }, - { - "name": "skysocks-client", - "auto_start": false, - "port": 13 - }, - { - "name": "vpn-server", - "auto_start": false, - "port": 44 - } - ], - "server_addr": "localhost:5505", - "bin_path": "/opt/skywire/apps" - }, - "hypervisors": [], - "cli_addr": "localhost:3435", - "log_level": "info", - "local_path": "/opt/skywire/local", - "stun_servers": [ - "172.104.188.139:3478", - "172.104.59.235:3478", - "172.104.183.187:3478", - "139.162.54.63:3478", - "172.105.115.97:3478", - "172.104.188.39:3478", - "172.104.188.140:3478", - "172.104.40.88:3478" - ], - "shutdown_timeout": "10s", - "restart_check_delay": "1s", - "is_public": false, - "persistent_transports": null -} \ No newline at end of file From cb14f5f3863e600ceac6f6219ab008013fda9320 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 13:49:43 -0500 Subject: [PATCH 14/19] implement -u --user flag for skywire-cli config gen & skywire-visor --- r | 90 --------------------------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 r diff --git a/r b/r deleted file mode 100644 index 1575585fe..000000000 --- a/r +++ /dev/null @@ -1,90 +0,0 @@ -{ - "version": "v0.6.0", - "sk": "a24666d8200f4b80ed711495cacc5bf32616611ae18cdf6c393ef04229cf8a94", - "pk": "03665141c243e6280d50688c4579b1b24c61f81c3ea78aff9435c12f1b8964f77d", - "dmsg": { - "discovery": "http://dmsgd.skywire.skycoin.com", - "sessions_count": 1, - "servers": [] - }, - "dmsgpty": { - "dmsg_port": 22, - "cli_network": "unix", - "cli_address": "/tmp/dmsgpty.sock" - }, - "skywire-tcp": { - "pk_table": null, - "listening_address": ":7777" - }, - "transport": { - "discovery": "http://tpd.skywire.skycoin.com", - "address_resolver": "http://ar.skywire.skycoin.com", - "public_autoconnect": true, - "transport_setup_nodes": null - }, - "routing": { - "setup_nodes": [ - "0324579f003e6b4048bae2def4365e634d8e0e3054a20fc7af49daf2a179658557" - ], - "route_finder": "http://rf.skywire.skycoin.com", - "route_finder_timeout": "10s", - "min_hops": 0 - }, - "uptime_tracker": { - "addr": "http://ut.skywire.skycoin.com" - }, - "launcher": { - "service_discovery": "http://sd.skycoin.com", - "apps": [ - { - "name": "vpn-client", - "auto_start": false, - "port": 43 - }, - { - "name": "skychat", - "args": [ - "-addr", - ":8001" - ], - "auto_start": true, - "port": 1 - }, - { - "name": "skysocks", - "auto_start": true, - "port": 3 - }, - { - "name": "skysocks-client", - "auto_start": false, - "port": 13 - }, - { - "name": "vpn-server", - "auto_start": false, - "port": 44 - } - ], - "server_addr": "localhost:5505", - "bin_path": "/opt/skywire/apps" - }, - "hypervisors": [], - "cli_addr": "localhost:3435", - "log_level": "info", - "local_path": "/opt/skywire/local", - "stun_servers": [ - "172.104.188.139:3478", - "172.104.59.235:3478", - "172.104.183.187:3478", - "139.162.54.63:3478", - "172.105.115.97:3478", - "172.104.188.39:3478", - "172.104.188.140:3478", - "172.104.40.88:3478" - ], - "shutdown_timeout": "10s", - "restart_check_delay": "1s", - "is_public": false, - "persistent_transports": null -} \ No newline at end of file From 1cb56a06ba643e73a798b2b26ab242aaced5fe82 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 14:01:41 -0500 Subject: [PATCH 15/19] fix default visor config name when unspecified --- cmd/skywire-cli/commands/config/gen.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index ee1f4b9f9..ea6789ed2 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -125,6 +125,7 @@ var genConfigCmd = &cobra.Command{ //set default output filename if output == "" { outunset = true + confPath = skyenv.ConfigName } else { confPath = output } @@ -149,7 +150,7 @@ var genConfigCmd = &cobra.Command{ //enable local hypervisor by default for user if usrEnv { hypervisor = true - } + } var err error if dmsgHTTP { dmsgHTTPPath := skyenv.DMSGHTTPName From eb20e122da300871d7326996dc23d6fbf62f7108 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Wed, 13 Apr 2022 14:34:35 -0500 Subject: [PATCH 16/19] revert apps back to using pflags --- cmd/apps/skychat/skychat.go | 112 +++------ cmd/apps/skysocks-client/skysocks-client.go | 146 ++++-------- cmd/apps/skysocks/skysocks.go | 117 +++------ cmd/apps/vpn-client/vpn-client.go | 252 ++++++++------------ cmd/apps/vpn-server/vpn-server.go | 152 +++++------- 5 files changed, 294 insertions(+), 485 deletions(-) diff --git a/cmd/apps/skychat/skychat.go b/cmd/apps/skychat/skychat.go index 7986c5ca8..b6e2f5698 100644 --- a/cmd/apps/skychat/skychat.go +++ b/cmd/apps/skychat/skychat.go @@ -7,6 +7,7 @@ import ( "context" "embed" "encoding/json" + "flag" "fmt" "io/fs" "net" @@ -16,10 +17,8 @@ import ( "sync" "time" - cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" "github.com/skycoin/skycoin/src/util/logging" - "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/cipher" @@ -35,95 +34,62 @@ const ( port = routing.Port(1) ) +var log = logging.MustGetLogger("chat") +var addr = flag.String("addr", ":8001", "address to bind") +var r = netutil.NewRetrier(log, 50*time.Millisecond, netutil.DefaultMaxBackoff, 5, 2) + var ( - // the go embed static points to skywire/cmd/apps/skychat/static - //go:embed static - embededFiles embed.FS - log = logging.MustGetLogger("chat") - r = netutil.NewRetrier(log, 50*time.Millisecond, netutil.DefaultMaxBackoff, 5, 2) - addr string - appC *app.Client - clientCh chan string - conns map[cipher.PubKey]net.Conn // Chat connections - connsMu sync.Mutex + appC *app.Client + clientCh chan string + conns map[cipher.PubKey]net.Conn // Chat connections + connsMu sync.Mutex ) -func init() { - rootCmd.Flags().SortFlags = false - rootCmd.Flags().StringVarP(&addr, "addr", "a", ":8001", "address to bind") -} +// the go embed static points to skywire/cmd/apps/skychat/static -var rootCmd = &cobra.Command{ - Use: "skychat", - Short: "Skywire P2P Message Application", - Long: ` - ┌─┐┬┌─┬ ┬┌─┐┬ ┬┌─┐┌┬┐ - └─┐├┴┐└┬┘│ ├─┤├─┤ │ - └─┘┴ ┴ ┴ └─┘┴ ┴┴ ┴ ┴ `, - Run: func(_ *cobra.Command, _ []string) { - appC = app.NewClient(nil) - defer appC.Close() - - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - fmt.Printf("Failed to output build info: %v", err) - } +//go:embed static +var embededFiles embed.FS - fmt.Print("Successfully started skychat.") +func main() { + appC = app.NewClient(nil) + defer appC.Close() - clientCh = make(chan string) - defer close(clientCh) + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + fmt.Printf("Failed to output build info: %v", err) + } - conns = make(map[cipher.PubKey]net.Conn) - go listenLoop() + flag.Parse() + fmt.Print("Successfully started skychat.") - if runtime.GOOS == "windows" { - ipcClient, err := ipc.StartClient(skyenv.SkychatName, nil) - if err != nil { - fmt.Printf("Error creating ipc server for skychat client: %v\n", err) - os.Exit(1) - } - go handleIPCSignal(ipcClient) - } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + clientCh = make(chan string) + defer close(clientCh) - http.Handle("/", http.FileServer(getFileSystem())) - http.HandleFunc("/message", messageHandler(ctx)) - http.HandleFunc("/sse", sseHandler) + conns = make(map[cipher.PubKey]net.Conn) + go listenLoop() - fmt.Print("Serving HTTP on", addr) - err := http.ListenAndServe(addr, nil) + if runtime.GOOS == "windows" { + ipcClient, err := ipc.StartClient(skyenv.SkychatName, nil) if err != nil { - fmt.Println(err) + fmt.Printf("Error creating ipc server for skychat client: %v\n", err) os.Exit(1) } - }, -} + go handleIPCSignal(ipcClient) + } + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() -// Execute executes root CLI command. -func Execute() { - cc.Init(&cc.Config{ - RootCmd: rootCmd, - Headings: cc.HiBlue + cc.Bold, - Commands: cc.HiBlue + cc.Bold, - CmdShortDescr: cc.HiBlue, - Example: cc.HiBlue + cc.Italic, - ExecName: cc.HiBlue + cc.Bold, - Flags: cc.HiBlue + cc.Bold, - FlagsDescr: cc.HiBlue, - NoExtraNewlines: true, - NoBottomNewline: true, - }) - - if err := rootCmd.Execute(); err != nil { + http.Handle("/", http.FileServer(getFileSystem())) + http.HandleFunc("/message", messageHandler(ctx)) + http.HandleFunc("/sse", sseHandler) + + fmt.Print("Serving HTTP on", *addr) + err := http.ListenAndServe(*addr, nil) + if err != nil { fmt.Println(err) + os.Exit(1) } } -func main() { - Execute() -} - func listenLoop() { l, err := appC.Listen(netType, port) if err != nil { diff --git a/cmd/apps/skysocks-client/skysocks-client.go b/cmd/apps/skysocks-client/skysocks-client.go index efb4f9af1..ac753691c 100644 --- a/cmd/apps/skysocks-client/skysocks-client.go +++ b/cmd/apps/skysocks-client/skysocks-client.go @@ -5,15 +5,13 @@ package main import ( "context" - "fmt" + "flag" "io" "net" "os" "time" - cc "github.com/ivanpirog/coloredcobra" "github.com/sirupsen/logrus" - "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire-utilities/pkg/cipher" @@ -30,78 +28,9 @@ const ( socksPort = routing.Port(3) ) -var ( - log = logrus.New() - r = netutil.NewRetrier(log, time.Second, netutil.DefaultMaxBackoff, 0, 1) - serverPK string - addr string -) - -func init() { - rootCmd.Flags().SortFlags = false - - rootCmd.Flags().StringVarP(&addr, "addr", "a", skyenv.SkysocksClientAddr, "Client address to listen on") - rootCmd.Flags().StringVarP(&serverPK, "srv", "q", "", "PubKey of the server to connect to") -} - -var rootCmd = &cobra.Command{ - Use: "skysocks-client", - Short: "Skywire SOCKS5 Proxy Client", - Long: ` - ┌─┐┬┌─┬ ┬┌─┐┌─┐┌─┐┬┌─┌─┐ ┌─┐┬ ┬┌─┐┌┐┌┌┬┐ - └─┐├┴┐└┬┘└─┐│ ││ ├┴┐└─┐───│ │ │├┤ │││ │ - └─┘┴ ┴ ┴ └─┘└─┘└─┘┴ ┴└─┘ └─┘┴─┘┴└─┘┘└┘ ┴ `, - Run: func(_ *cobra.Command, _ []string) { - appC := app.NewClient(nil) - defer appC.Close() - - skysocks.Log = log - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - log.Printf("Failed to output build info: %v", err) - } - - if serverPK == "" { - log.Warn("Empty server PubKey. Exiting") - return - } +var log = logrus.New() - pk := cipher.PubKey{} - if err := pk.UnmarshalText([]byte(serverPK)); err != nil { - log.Fatal("Invalid server PubKey: ", err) - } - - for { - conn, err := dialServer(ctx, appC, pk) - if err != nil { - log.Fatalf("Failed to dial to a server: %v", err) - } - - log.Printf("Connected to %v\n", pk) - - client, err := skysocks.NewClient(conn) - if err != nil { - log.Fatal("Failed to create a new client: ", err) - } - - log.Printf("Serving proxy client %v\n", addr) - - if err := client.ListenAndServe(addr); err != nil { - log.Errorf("Error serving proxy client: %v\n", err) - } - - // need to filter this out, cause usually client failure means app conn is already closed - if err := conn.Close(); err != nil && err != io.ErrClosedPipe { - log.Errorf("Error closing app conn: %v\n", err) - } - - log.Println("Reconnecting to skysocks server") - } - }, -} +var r = netutil.NewRetrier(log, time.Second, netutil.DefaultMaxBackoff, 0, 1) func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.Conn, error) { var conn net.Conn @@ -121,26 +50,57 @@ func dialServer(ctx context.Context, appCl *app.Client, pk cipher.PubKey) (net.C return conn, nil } -// Execute executes root CLI command. -func Execute() { - cc.Init(&cc.Config{ - RootCmd: rootCmd, - Headings: cc.HiBlue + cc.Bold, - Commands: cc.HiBlue + cc.Bold, - CmdShortDescr: cc.HiBlue, - Example: cc.HiBlue + cc.Italic, - ExecName: cc.HiBlue + cc.Bold, - Flags: cc.HiBlue + cc.Bold, - FlagsDescr: cc.HiBlue, - NoExtraNewlines: true, - NoBottomNewline: true, - }) +func main() { + appC := app.NewClient(nil) + defer appC.Close() + + skysocks.Log = log + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + log.Printf("Failed to output build info: %v", err) } -} -func main() { - Execute() + var addr = flag.String("addr", skyenv.SkysocksClientAddr, "Client address to listen on") + var serverPK = flag.String("srv", "", "PubKey of the server to connect to") + flag.Parse() + + if *serverPK == "" { + log.Warn("Empty server PubKey. Exiting") + return + } + + pk := cipher.PubKey{} + if err := pk.UnmarshalText([]byte(*serverPK)); err != nil { + log.Fatal("Invalid server PubKey: ", err) + } + + for { + conn, err := dialServer(ctx, appC, pk) + if err != nil { + log.Fatalf("Failed to dial to a server: %v", err) + } + + log.Printf("Connected to %v\n", pk) + + client, err := skysocks.NewClient(conn) + if err != nil { + log.Fatal("Failed to create a new client: ", err) + } + + log.Printf("Serving proxy client %v\n", *addr) + + if err := client.ListenAndServe(*addr); err != nil { + log.Errorf("Error serving proxy client: %v\n", err) + } + + // need to filter this out, cause usually client failure means app conn is already closed + if err := conn.Close(); err != nil && err != io.ErrClosedPipe { + log.Errorf("Error closing app conn: %v\n", err) + } + + log.Println("Reconnecting to skysocks server") + } } diff --git a/cmd/apps/skysocks/skysocks.go b/cmd/apps/skysocks/skysocks.go index 5bf56867f..53eb71a7b 100644 --- a/cmd/apps/skysocks/skysocks.go +++ b/cmd/apps/skysocks/skysocks.go @@ -4,15 +4,14 @@ proxy server app for skywire visor package main import ( + "flag" "fmt" "os" "os/signal" "runtime" - cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" "github.com/sirupsen/logrus" - "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/buildinfo" "github.com/skycoin/skywire/internal/skysocks" @@ -27,95 +26,57 @@ const ( port routing.Port = 3 ) -var ( - log = logrus.New() - passcode string -) +var log = logrus.New() -func init() { - rootCmd.Flags().SortFlags = false +func main() { + appC := app.NewClient(nil) + defer appC.Close() - rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") -} + skysocks.Log = log -var rootCmd = &cobra.Command{ - Use: "skysocks", - Short: "Skywire SOCKS5 Proxy Server", - Long: ` - ┌─┐┬┌─┬ ┬┌─┐┌─┐┌─┐┬┌─┌─┐ - └─┐├┴┐└┬┘└─┐│ ││ ├┴┐└─┐ - └─┘┴ ┴ ┴ └─┘└─┘└─┘┴ ┴└─┘`, - Run: func(_ *cobra.Command, _ []string) { - appC := app.NewClient(nil) - defer appC.Close() - - skysocks.Log = log - - if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { - fmt.Printf("Failed to output build info: %v", err) - } + if _, err := buildinfo.Get().WriteTo(os.Stdout); err != nil { + fmt.Printf("Failed to output build info: %v", err) + } - srv, err := skysocks.NewServer(passcode, log) - if err != nil { - log.Fatal("Failed to create a new server: ", err) - } + var passcode = flag.String("passcode", "", "Authorize user against this passcode") + flag.Parse() + + srv, err := skysocks.NewServer(*passcode, log) + if err != nil { + log.Fatal("Failed to create a new server: ", err) + } + + l, err := appC.Listen(netType, port) + if err != nil { + log.Fatalf("Error listening network %v on port %d: %v\n", netType, port, err) + } + + fmt.Println("Starting serving proxy server") - l, err := appC.Listen(netType, port) + if runtime.GOOS == "windows" { + ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) if err != nil { - log.Fatalf("Error listening network %v on port %d: %v\n", netType, port, err) + fmt.Printf("Error creating ipc server for VPN client: %v\n", err) + os.Exit(1) } + go srv.ListenIPC(ipcClient) + } else { + termCh := make(chan os.Signal, 1) + signal.Notify(termCh, os.Interrupt) - fmt.Println("Starting serving proxy server") + go func() { + <-termCh - if runtime.GOOS == "windows" { - ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) - if err != nil { - fmt.Printf("Error creating ipc server for VPN client: %v\n", err) + if err := srv.Close(); err != nil { + fmt.Println(err) os.Exit(1) } - go srv.ListenIPC(ipcClient) - } else { - termCh := make(chan os.Signal, 1) - signal.Notify(termCh, os.Interrupt) - - go func() { - <-termCh - - if err := srv.Close(); err != nil { - fmt.Println(err) - os.Exit(1) - } - }() + }() - } - - if err := srv.Serve(l); err != nil { - fmt.Println(err) - os.Exit(1) - } - }, -} + } -// Execute executes root CLI command. -func Execute() { - cc.Init(&cc.Config{ - RootCmd: rootCmd, - Headings: cc.HiBlue + cc.Bold, - Commands: cc.HiBlue + cc.Bold, - CmdShortDescr: cc.HiBlue, - Example: cc.HiBlue + cc.Italic, - ExecName: cc.HiBlue + cc.Bold, - Flags: cc.HiBlue + cc.Bold, - FlagsDescr: cc.HiBlue, - NoExtraNewlines: true, - NoBottomNewline: true, - }) - - if err := rootCmd.Execute(); err != nil { + if err := srv.Serve(l); err != nil { fmt.Println(err) + os.Exit(1) } } - -func main() { - Execute() -} diff --git a/cmd/apps/vpn-client/vpn-client.go b/cmd/apps/vpn-client/vpn-client.go index 5c508290c..2e61ab501 100644 --- a/cmd/apps/vpn-client/vpn-client.go +++ b/cmd/apps/vpn-client/vpn-client.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "net" "os" @@ -8,9 +9,7 @@ import ( "runtime" "syscall" - cc "github.com/ivanpirog/coloredcobra" ipc "github.com/james-barrow/golang-ipc" - "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire/internal/vpn" @@ -20,183 +19,142 @@ import ( ) var ( - serverPKStr string - localPKStr string - localSKStr string - passcode string - killswitch bool + serverPKStr = flag.String("srv", "", "PubKey of the server to connect to") + localPKStr = flag.String("pk", "", "Local PubKey") + localSKStr = flag.String("sk", "", "Local SecKey") + passcode = flag.String("passcode", "", "Passcode to authenticate connection") + killswitch = flag.Bool("killswitch", false, "If set, the Internet won't be restored during reconnection attempts") ) -func init() { - rootCmd.Flags().SortFlags = false +func main() { + flag.Parse() - rootCmd.Flags().StringVarP(&serverPKStr, "srv", "q", "", "PubKey of the server to connect to") - rootCmd.Flags().StringVarP(&localPKStr, "pk", "p", "", "Local PubKey") - rootCmd.Flags().StringVarP(&localSKStr, "sk", "s", "", "Local SecKey") - rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") - rootCmd.Flags().BoolVarP(&killswitch, "killswitch", "k", false, "If set, the Internet won't be restored during reconnection attempts") -} + if *serverPKStr == "" { + // TODO(darkrengarius): fix args passage for Windows + //*serverPKStr = "03e9019b3caa021dbee1c23e6295c6034ab4623aec50802fcfdd19764568e2958d" + fmt.Println("VPN server pub key is missing") + os.Exit(1) + } -var rootCmd = &cobra.Command{ - Use: "vpn-client", - Short: "Skywire VPN Client", - Long: ` - ┬ ┬┌─┐┌┐┌ ┌─┐┬ ┬┌─┐┌┐┌┌┬┐ - └┐┌┘├─┘│││───│ │ │├┤ │││ │ - └┘ ┴ ┘└┘ └─┘┴─┘┴└─┘┘└┘ ┴ `, - Run: func(_ *cobra.Command, _ []string) { - if serverPKStr == "" { - // TODO(darkrengarius): fix args passage for Windows - //*serverPKStr = "03e9019b3caa021dbee1c23e6295c6034ab4623aec50802fcfdd19764568e2958d" - fmt.Println("VPN server pub key is missing") + serverPK := cipher.PubKey{} + if err := serverPK.UnmarshalText([]byte(*serverPKStr)); err != nil { + fmt.Printf("Invalid VPN server pub key: %v\n", err) + os.Exit(1) + } + + localPK := cipher.PubKey{} + if *localPKStr != "" { + if err := localPK.UnmarshalText([]byte(*localPKStr)); err != nil { + fmt.Printf("Invalid local PK: %v\n", err) os.Exit(1) } + } - serverPK := cipher.PubKey{} - if err := serverPK.UnmarshalText([]byte(serverPKStr)); err != nil { - fmt.Printf("Invalid VPN server pub key: %v\n", err) + localSK := cipher.SecKey{} + if *localSKStr != "" { + if err := localSK.UnmarshalText([]byte(*localSKStr)); err != nil { + fmt.Printf("Invalid local SK: %v\n", err) os.Exit(1) } + } - localPK := cipher.PubKey{} - if localPKStr != "" { - if err := localPK.UnmarshalText([]byte(localPKStr)); err != nil { - fmt.Printf("Invalid local PK: %v\n", err) - os.Exit(1) - } - } + var directIPsCh, nonDirectIPsCh = make(chan net.IP, 100), make(chan net.IP, 100) + defer close(directIPsCh) + defer close(nonDirectIPsCh) - localSK := cipher.SecKey{} - if localSKStr != "" { - if err := localSK.UnmarshalText([]byte(localSKStr)); err != nil { - fmt.Printf("Invalid local SK: %v\n", err) - os.Exit(1) - } - } + eventSub := appevent.NewSubscriber() - var directIPsCh, nonDirectIPsCh = make(chan net.IP, 100), make(chan net.IP, 100) - defer close(directIPsCh) - defer close(nonDirectIPsCh) + parseIP := func(addr string) net.IP { + ip, ok, err := vpn.ParseIP(addr) + if err != nil { + fmt.Printf("Failed to parse IP %s: %v\n", addr, err) + return nil + } + if !ok { + fmt.Printf("Failed to parse IP %s\n", addr) + return nil + } - eventSub := appevent.NewSubscriber() + return ip + } - parseIP := func(addr string) net.IP { - ip, ok, err := vpn.ParseIP(addr) - if err != nil { - fmt.Printf("Failed to parse IP %s: %v\n", addr, err) - return nil - } - if !ok { - fmt.Printf("Failed to parse IP %s\n", addr) - return nil - } + eventSub.OnTCPDial(func(data appevent.TCPDialData) { + if ip := parseIP(data.RemoteAddr); ip != nil { + directIPsCh <- ip + } + }) - return ip + eventSub.OnTCPClose(func(data appevent.TCPCloseData) { + if ip := parseIP(data.RemoteAddr); ip != nil { + nonDirectIPsCh <- ip } + }) - eventSub.OnTCPDial(func(data appevent.TCPDialData) { - if ip := parseIP(data.RemoteAddr); ip != nil { - directIPsCh <- ip - } - }) + appClient := app.NewClient(eventSub) + defer appClient.Close() - eventSub.OnTCPClose(func(data appevent.TCPCloseData) { - if ip := parseIP(data.RemoteAddr); ip != nil { - nonDirectIPsCh <- ip - } - }) + fmt.Printf("Connecting to VPN server %s\n", serverPK.String()) - appClient := app.NewClient(eventSub) - defer appClient.Close() + vpnClientCfg := vpn.ClientConfig{ + Passcode: *passcode, + Killswitch: *killswitch, + ServerPK: serverPK, + } - fmt.Printf("Connecting to VPN server %s\n", serverPK.String()) + vpnClient, err := vpn.NewClient(vpnClientCfg, appClient) + if err != nil { + fmt.Printf("Error creating VPN client: %v\n", err) + } - vpnClientCfg := vpn.ClientConfig{ - Passcode: passcode, - Killswitch: killswitch, - ServerPK: serverPK, + var directRoutesDone bool + for !directRoutesDone { + select { + case ip := <-directIPsCh: + if err := vpnClient.AddDirectRoute(ip); err != nil { + fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) + } + default: + directRoutesDone = true } + } - vpnClient, err := vpn.NewClient(vpnClientCfg, appClient) - if err != nil { - fmt.Printf("Error creating VPN client: %v\n", err) + go func() { + for ip := range directIPsCh { + if err := vpnClient.AddDirectRoute(ip); err != nil { + fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) + } } + }() - var directRoutesDone bool - for !directRoutesDone { - select { - case ip := <-directIPsCh: - if err := vpnClient.AddDirectRoute(ip); err != nil { - fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) - } - default: - directRoutesDone = true + go func() { + for ip := range nonDirectIPsCh { + if err := vpnClient.RemoveDirectRoute(ip); err != nil { + fmt.Printf("Failed to remove direct route to %s: %v\n", ip.String(), err) } } + }() - go func() { - for ip := range directIPsCh { - if err := vpnClient.AddDirectRoute(ip); err != nil { - fmt.Printf("Failed to setup direct route to %s: %v\n", ip.String(), err) - } - } - }() + if runtime.GOOS != "windows" { + osSigs := make(chan os.Signal, 2) + sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} + for _, sig := range sigs { + signal.Notify(osSigs, sig) + } go func() { - for ip := range nonDirectIPsCh { - if err := vpnClient.RemoveDirectRoute(ip); err != nil { - fmt.Printf("Failed to remove direct route to %s: %v\n", ip.String(), err) - } - } + <-osSigs + vpnClient.Close() }() - - if runtime.GOOS != "windows" { - osSigs := make(chan os.Signal, 2) - sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} - for _, sig := range sigs { - signal.Notify(osSigs, sig) - } - - go func() { - <-osSigs - vpnClient.Close() - }() - } else { - ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) - if err != nil { - fmt.Printf("Error creating ipc server for VPN client: %v\n", err) - os.Exit(1) - } - go vpnClient.ListenIPC(ipcClient) - } - - if err := vpnClient.Serve(); err != nil { - fmt.Printf("Failed to serve VPN: %v\n", err) + } else { + ipcClient, err := ipc.StartClient(skyenv.VPNClientName, nil) + if err != nil { + fmt.Printf("Error creating ipc server for VPN client: %v\n", err) + os.Exit(1) } - - }, -} - -// Execute executes root CLI command. -func Execute() { - cc.Init(&cc.Config{ - RootCmd: rootCmd, - Headings: cc.HiBlue + cc.Bold, - Commands: cc.HiBlue + cc.Bold, - CmdShortDescr: cc.HiBlue, - Example: cc.HiBlue + cc.Italic, - ExecName: cc.HiBlue + cc.Bold, - Flags: cc.HiBlue + cc.Bold, - FlagsDescr: cc.HiBlue, - NoExtraNewlines: true, - NoBottomNewline: true, - }) - - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) + go vpnClient.ListenIPC(ipcClient) } -} -func main() { - Execute() + if err := vpnClient.Serve(); err != nil { + fmt.Printf("Failed to serve VPN: %v\n", err) + } } diff --git a/cmd/apps/vpn-server/vpn-server.go b/cmd/apps/vpn-server/vpn-server.go index 6923f4e2c..54066cffe 100644 --- a/cmd/apps/vpn-server/vpn-server.go +++ b/cmd/apps/vpn-server/vpn-server.go @@ -1,14 +1,13 @@ package main import ( - "fmt" + "flag" "os" "os/signal" + "runtime" "syscall" - cc "github.com/ivanpirog/coloredcobra" "github.com/sirupsen/logrus" - "github.com/spf13/cobra" "github.com/skycoin/skywire-utilities/pkg/cipher" "github.com/skycoin/skywire/internal/vpn" @@ -28,112 +27,77 @@ var ( ) var ( - localPKStr string - localSKStr string - passcode string - secure bool + localPKStr = flag.String("pk", "", "Local PubKey") + localSKStr = flag.String("sk", "", "Local SecKey") + passcode = flag.String("passcode", "", "Passcode to authenticate connecting users") + secure = flag.Bool("secure", true, "Forbid connections from clients to server local network") ) -func init() { - rootCmd.Flags().SortFlags = false +func main() { + if runtime.GOOS != "linux" { + log.Fatalln("OS is not supported") + } - rootCmd.Flags().StringVarP(&localPKStr, "pk", "p", "", "Local PubKey") - rootCmd.Flags().StringVarP(&localSKStr, "sk", "s", "", "Local SecKey") - rootCmd.Flags().StringVarP(&passcode, "passcode", "r", "", "Passcode to authenticate connection") - rootCmd.Flags().BoolVarP(&secure, "secure", "k", true, "Forbid connections from clients to server local network") -} + flag.Parse() -var rootCmd = &cobra.Command{ - Use: "vpn-server", - Short: "Skywire VPN Server", - Long: ` - ┬ ┬┌─┐┌┐┌ ┌─┐┌─┐┬─┐┬ ┬┌─┐┬─┐ - └┐┌┘├─┘│││───└─┐├┤ ├┬┘└┐┌┘├┤ ├┬┘ - └┘ ┴ ┘└┘ └─┘└─┘┴└─ └┘ └─┘┴└─`, - Run: func(_ *cobra.Command, _ []string) { - localPK := cipher.PubKey{} - if localPKStr != "" { - if err := localPK.UnmarshalText([]byte(localPKStr)); err != nil { - log.WithError(err).Fatalln("Invalid local PK") - } + localPK := cipher.PubKey{} + if *localPKStr != "" { + if err := localPK.UnmarshalText([]byte(*localPKStr)); err != nil { + log.WithError(err).Fatalln("Invalid local PK") } + } - localSK := cipher.SecKey{} - if localSKStr != "" { - if err := localSK.UnmarshalText([]byte(localSKStr)); err != nil { - log.WithError(err).Fatalln("Invalid local SK") - } + localSK := cipher.SecKey{} + if *localSKStr != "" { + if err := localSK.UnmarshalText([]byte(*localSKStr)); err != nil { + log.WithError(err).Fatalln("Invalid local SK") } + } - appClient := app.NewClient(nil) - defer appClient.Close() + appClient := app.NewClient(nil) + defer appClient.Close() - osSigs := make(chan os.Signal, 2) + osSigs := make(chan os.Signal, 2) - sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} - for _, sig := range sigs { - signal.Notify(osSigs, sig) - } + sigs := []os.Signal{syscall.SIGTERM, syscall.SIGINT} + for _, sig := range sigs { + signal.Notify(osSigs, sig) + } - l, err := appClient.Listen(netType, vpnPort) - if err != nil { - log.WithError(err).Errorf("Error listening network %v on port %d", netType, vpnPort) - return - } + l, err := appClient.Listen(netType, vpnPort) + if err != nil { + log.WithError(err).Errorf("Error listening network %v on port %d", netType, vpnPort) + return + } - log.Infof("Got app listener, bound to %d", vpnPort) + log.Infof("Got app listener, bound to %d", vpnPort) - srvCfg := vpn.ServerConfig{ - Passcode: passcode, - Secure: secure, - } - srv, err := vpn.NewServer(srvCfg, log) - if err != nil { - log.WithError(err).Fatalln("Error creating VPN server") + srvCfg := vpn.ServerConfig{ + Passcode: *passcode, + Secure: *secure, + } + srv, err := vpn.NewServer(srvCfg, log) + if err != nil { + log.WithError(err).Fatalln("Error creating VPN server") + } + defer func() { + if err := srv.Close(); err != nil { + log.WithError(err).Errorln("Error closing server") } - defer func() { - if err := srv.Close(); err != nil { - log.WithError(err).Errorln("Error closing server") - } - }() - - errCh := make(chan error) - go func() { - if err := srv.Serve(l); err != nil { - errCh <- err - } - - close(errCh) - }() - - select { - case <-osSigs: - case err := <-errCh: - log.WithError(err).Errorln("Error serving") + }() + + errCh := make(chan error) + go func() { + if err := srv.Serve(l); err != nil { + errCh <- err } - }, -} -// Execute executes root CLI command. -func Execute() { - cc.Init(&cc.Config{ - RootCmd: rootCmd, - Headings: cc.HiBlue + cc.Bold, - Commands: cc.HiBlue + cc.Bold, - CmdShortDescr: cc.HiBlue, - Example: cc.HiBlue + cc.Italic, - ExecName: cc.HiBlue + cc.Bold, - Flags: cc.HiBlue + cc.Bold, - FlagsDescr: cc.HiBlue, - NoExtraNewlines: true, - NoBottomNewline: true, - }) - - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - } -} + close(errCh) + }() -func main() { - Execute() + select { + case <-osSigs: + case err := <-errCh: + log.WithError(err).Errorln("Error serving") + } } From 20aa58f7d046845f136893673bb1f23d1fbb5dc7 Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Thu, 14 Apr 2022 10:55:49 -0500 Subject: [PATCH 17/19] change fail to warn about writing with elevated permissions. Make logging more descriptive around these errors. Add dtection of unpublised changes since commit in logging --- cmd/skywire-visor/commands/root.go | 42 +++++++++++++++++++----------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/cmd/skywire-visor/commands/root.go b/cmd/skywire-visor/commands/root.go index 7c52afca4..aea706c9b 100644 --- a/cmd/skywire-visor/commands/root.go +++ b/cmd/skywire-visor/commands/root.go @@ -107,7 +107,7 @@ func init() { } } if _, err := os.Stat(skyenv.HomePath() + "/" + skyenv.ConfigName); err == nil { - rootCmd.Flags().BoolVarP(&usr, "user", "u", false, "use config at: "+skyenv.HomePath()+"/"+skyenv.ConfigName) + rootCmd.Flags().BoolVarP(&usr, "user", "u", false, "use config at: $HOME/"+skyenv.ConfigName) } rootCmd.Flags().StringVarP(&pprofMode, "pprofmode", "p", "", "pprof mode: cpu, mem, mutex, block, trace, http") hiddenflags = append(hiddenflags, "pprofmode") @@ -209,6 +209,7 @@ var rootCmd = &cobra.Command{ } var fork string var branch string + var nocommit string //indicates how skywire was started skywire = os.Args[0] //indicates where skywire was started @@ -233,8 +234,10 @@ var rootCmd = &cobra.Command{ if version, err := script.Exec(`git describe`).String(); err == nil { visorBuildInfo.Version = strings.ReplaceAll(version, "\n", "") if visorBuildInfo.Commit == "unknown" { - if commit, err := script.Exec(`git rev-list -1 HEAD`).String(); err == nil { - visorBuildInfo.Commit = strings.ReplaceAll(commit, "\n", "") + if nocommit, err = script.Exec(`git diff-index HEAD --`).String(); err == nil { + if commit, err := script.Exec(`git rev-list -1 HEAD`).String(); err == nil { + visorBuildInfo.Commit = strings.ReplaceAll(commit, "\n", "") + } } } if fork, err = script.Exec(`git config --get remote.origin.url`).String(); err == nil { @@ -269,18 +272,23 @@ var rootCmd = &cobra.Command{ } } } - log.WithField("version: ", visorBuildInfo.Version).Info() + log.WithField("version", visorBuildInfo.Version).Info() if visorBuildInfo.Date != "unknown" && visorBuildInfo.Date != "" { - log.WithField("built on: ", visorBuildInfo.Date).Info() + log.WithField("built on", visorBuildInfo.Date).Info() } if visorBuildInfo.Commit != "unknown" && visorBuildInfo.Commit != "" { - log.WithField("against commit: ", visorBuildInfo.Commit).Info() + if (nocommit != "") && (nocommit != "\n") { + log.Info("with changes since commit") + log.WithField("commit", visorBuildInfo.Commit).Info() + } else { + log.WithField("against commit", visorBuildInfo.Commit).Info() + } if fork != "" { - log.WithField("fork: ", fork).Info() + log.WithField("fork", fork).Info() } } if branch != "unknown" && branch != "" { - log.WithField("branch: ", branch).Info() + log.WithField("branch", branch).Info() } }, Run: func(_ *cobra.Command, _ []string) { @@ -302,17 +310,21 @@ func runVisor(conf *visorconfig.V1) { conf = initConfig(log, confPath) } - //dont create files & directories as root in non root-owned dir + //warn about creating files & directories as root in non root-owned dir if _, err := exec.LookPath("stat"); err == nil { - if owner, err := script.Exec(`stat -c '%U' ` + conf.LocalPath + "/..").String(); err == nil { + pathtolocalpath := strings.ReplaceAll(conf.LocalPath, "local", "") + if owner, err := script.Exec(`stat -c '%U' ` + pathtolocalpath).String(); err == nil { if ((owner != "root") || (owner != "root\n")) && root { - log.WithField("local path: ", conf.LocalPath).Error() - log.Fatal("not writing as root to local path not owned by root") + log.WithField("local path", conf.LocalPath).Warn() + log.Warn("writing as root to directory not owned by root!") } - //similarly, anticipate and fail on the reverse instance + } + // fail on the reverse instance + if owner, err := script.Exec(`stat -c '%U' ` + conf.LocalPath).String(); err == nil { if ((owner == "root") || (owner == "root\n")) && !root { - log.WithField("local path: ", conf.LocalPath).Error() - log.Fatal("Insufficient permissions to write to the local path") + log.WithField("local path", conf.LocalPath).WithField("owner", "root").Error("folder belongs to root") + log.WithField("visor is root", root).Error("visor not started as root") + log.Fatal("Insufficient permissions to write to the local path: " + conf.LocalPath) } } } From 54c17d644a1c8f491c42d646c54cfaf80b3bde3b Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Fri, 15 Apr 2022 08:51:55 -0500 Subject: [PATCH 18/19] cleanup per @jdknives suggestions --- cmd/skywire-cli/commands/config/gen.go | 14 +++++++++----- internal/gui/gui.go | 4 ++-- internal/gui/gui_unix.go | 11 +++++------ pkg/skyenv/values_darwin.go | 2 +- pkg/skyenv/values_linux.go | 2 +- pkg/skyenv/values_windows.go | 2 +- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index ea6789ed2..2e95eb224 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -83,7 +83,10 @@ func init() { hiddenflags = append(hiddenflags, "stdout") genConfigCmd.Flags().StringVarP(&output, "out", "o", "", "output config: "+skyenv.ConfigName) genConfigCmd.Flags().BoolVarP(&pkgEnv, "pkg", "p", false, "use paths for package: "+skyenv.SkywirePath) - genConfigCmd.Flags().BoolVarP(&usrEnv, "user", "u", false, "use paths for user space: "+skyenv.HomePath()) + homepath := skyenv.HomePath() + if homepath != "" { + genConfigCmd.Flags().BoolVarP(&usrEnv, "user", "u", false, "use paths for user space: "+homepath) + } genConfigCmd.Flags().BoolVarP(&publicRPC, "publicrpc", "q", false, "allow rpc requests from LAN") hiddenflags = append(hiddenflags, "publicrpc") genConfigCmd.Flags().BoolVarP(®en, "regen", "r", false, "re-generate existing config & retain keys") @@ -335,13 +338,14 @@ var genConfigCmd = &cobra.Command{ } //don't write file with stdout if !stdout { - thisUser, err := user.Current() + userLvl, err := user.Current() if err != nil { - panic(err) - } - if thisUser.Username == "root" { + logger.WithError(err).Error("Failed to detect user.") + } else { + if userLvl.Username == "root" { root = true } + } //dont write config as root to non root owned dir & vice versa if _, err = exec.LookPath("stat"); err == nil { diff --git a/internal/gui/gui.go b/internal/gui/gui.go index 5a9091ae1..9f7783153 100644 --- a/internal/gui/gui.go +++ b/internal/gui/gui.go @@ -71,7 +71,7 @@ func GetOnGUIReady(icon []byte, conf *visorconfig.V1) (ret func()) { httpC := getHTTPClient(conf, context.Background(), logger) - if checkRoot() { + if isRoot() { ret = func() { systray.SetTemplateIcon(icon, icon) systray.SetTooltip("Skywire") @@ -82,7 +82,7 @@ func GetOnGUIReady(icon []byte, conf *visorconfig.V1) (ret func()) { go handleRootInteraction(conf, doneCh) } } - if !checkRoot() { + if !isRoot() { ret = func() { systray.SetTemplateIcon(icon, icon) systray.SetTooltip("Skywire") diff --git a/internal/gui/gui_unix.go b/internal/gui/gui_unix.go index f2e110baf..f7774f747 100644 --- a/internal/gui/gui_unix.go +++ b/internal/gui/gui_unix.go @@ -13,13 +13,12 @@ func platformExecUninstall() error { return osutil.Run("/bin/bash", "-c", deinstallerPath) } -func checkRoot() bool { - thisUser, err := user.Current() - if err != nil { - panic(err) - } - if thisUser.Username == "root" { +func isRoot() bool { + userLvl, err := user.Current() + if err == nil { + if userLvl.Username == "root" { return true } +} return false } diff --git a/pkg/skyenv/values_darwin.go b/pkg/skyenv/values_darwin.go index 01745ce15..9c42b076e 100644 --- a/pkg/skyenv/values_darwin.go +++ b/pkg/skyenv/values_darwin.go @@ -25,7 +25,7 @@ func UserConfig() PkgConfig { var usrconfig PkgConfig usrconfig.Launcher.BinPath = "/Library/Application Support/Skywire/apps" usrconfig.LocalPath = HomePath() + "/.skywire/local" - usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" usrconfig.Hypervisor.EnableAuth = true return usrconfig } diff --git a/pkg/skyenv/values_linux.go b/pkg/skyenv/values_linux.go index 041d1022a..b30a0febf 100644 --- a/pkg/skyenv/values_linux.go +++ b/pkg/skyenv/values_linux.go @@ -25,7 +25,7 @@ func UserConfig() PkgConfig { var usrconfig PkgConfig usrconfig.Launcher.BinPath = "/opt/skywire/apps" usrconfig.LocalPath = HomePath() + "/.skywire/local" - usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" usrconfig.Hypervisor.EnableAuth = true return usrconfig } diff --git a/pkg/skyenv/values_windows.go b/pkg/skyenv/values_windows.go index 08fd29153..7329fa49c 100644 --- a/pkg/skyenv/values_windows.go +++ b/pkg/skyenv/values_windows.go @@ -25,7 +25,7 @@ func UserConfig() PkgConfig { var usrconfig PkgConfig usrconfig.Launcher.BinPath = "C:/Program Files/Skywire/apps" usrconfig.LocalPath = HomePath() + "/.skywire/local" - usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" //permissions errors if the process is not run as root. + usrconfig.Hypervisor.DbPath = HomePath() + "/.skywire/users.db" usrconfig.Hypervisor.EnableAuth = true return usrconfig } From 78942744b578c4a8c9fa18cefc0f1eb3b11a52ed Mon Sep 17 00:00:00 2001 From: Moses Narrow Date: Fri, 15 Apr 2022 08:53:21 -0500 Subject: [PATCH 19/19] make format check --- cmd/skywire-cli/commands/config/gen.go | 4 ++-- internal/gui/gui_unix.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/skywire-cli/commands/config/gen.go b/cmd/skywire-cli/commands/config/gen.go index 2e95eb224..b545ff20d 100644 --- a/cmd/skywire-cli/commands/config/gen.go +++ b/cmd/skywire-cli/commands/config/gen.go @@ -343,9 +343,9 @@ var genConfigCmd = &cobra.Command{ logger.WithError(err).Error("Failed to detect user.") } else { if userLvl.Username == "root" { - root = true + root = true + } } - } //dont write config as root to non root owned dir & vice versa if _, err = exec.LookPath("stat"); err == nil { diff --git a/internal/gui/gui_unix.go b/internal/gui/gui_unix.go index f7774f747..3f3b2cfbe 100644 --- a/internal/gui/gui_unix.go +++ b/internal/gui/gui_unix.go @@ -16,9 +16,9 @@ func platformExecUninstall() error { func isRoot() bool { userLvl, err := user.Current() if err == nil { - if userLvl.Username == "root" { - return true + if userLvl.Username == "root" { + return true + } } -} return false }