From 1238eb14e61609a3604d279becddef4be2f58cf2 Mon Sep 17 00:00:00 2001 From: David Pinheiro Date: Sat, 11 May 2019 13:53:12 -0700 Subject: [PATCH] Add support for Windows This change modifies how the user home directory is retrieved to use `os.UserHomeDir()` which is suppported on different platforms (e.g. mac, linux, windows) Closes #47 --- .gitignore | 6 ++++++ Makefile | 4 ++++ cmd/mole/main.go | 9 ++++++++- storage/storage.go | 25 ++++++++++++++++++++----- storage/storage_test.go | 1 + tunnel/config.go | 8 +++++++- tunnel/tunnel.go | 14 ++++++++++++-- tunnel/tunnel_test.go | 2 +- 8 files changed, 59 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 036513c..2f1c415 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ /test-env/key /test-env/key.pub + +/tunnel/testdata/.ssh + +*.swp +*~ +*.un~ diff --git a/Makefile b/Makefile index 8dcdf55..d69383e 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.PHONY: test cover install bin test-env rm-test-env + LDFLAGS := -X main.version=$(version) test: @@ -19,6 +21,8 @@ endif cd bin && tar c mole | gzip > mole$(version).darwin-amd64.tar.gz && rm mole && cd - GOOS=linux GOARCH=amd64 go build -o bin/mole -ldflags "$(LDFLAGS)" github.com/davrodpin/mole/cmd/mole cd bin && tar c mole | gzip > mole$(version).linux-amd64.tar.gz && rm mole && cd - + GOOS=windows GOARCH=amd64 go build -o bin/mole.exe -ldflags "$(LDFLAGS)" github.com/davrodpin/mole/cmd/mole + cd bin && tar c mole.exe | gzip > mole$(version).windows-amd64.tar.gz && rm mole.exe && cd - add-network: -@docker network create --subnet=192.168.33.0/24 mole diff --git a/cmd/mole/main.go b/cmd/mole/main.go index cc0970e..501b349 100644 --- a/cmd/mole/main.go +++ b/cmd/mole/main.go @@ -33,9 +33,16 @@ func main() { app.PrintUsage() os.Exit(1) } + log.SetOutput(os.Stdout) - instancesDir = fmt.Sprintf("%s/.mole/instances", os.Getenv("HOME")) + home, err := os.UserHomeDir() + if err != nil { + log.Errorf("error starting mole: %v", err) + os.Exit(1) + } + + instancesDir = fmt.Sprintf("%s/.mole/instances", home) err = createInstancesDir() if err != nil { diff --git a/storage/storage.go b/storage/storage.go index 62218c4..c364997 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -97,7 +97,12 @@ func Remove(name string) (*Tunnel, error) { func loadStore() (*Store, error) { var store *Store - if _, err := os.Stat(storePath()); err != nil { + sp, err := storePath() + if err != nil { + return nil, err + } + + if _, err := os.Stat(sp); err != nil { store = &Store{Tunnels: make(map[string]*Tunnel)} store, err = createStore(store) if err != nil { @@ -107,7 +112,7 @@ func loadStore() (*Store, error) { return store, nil } - if _, err := toml.DecodeFile(storePath(), &store); err != nil { + if _, err := toml.DecodeFile(sp, &store); err != nil { return nil, err } @@ -115,7 +120,12 @@ func loadStore() (*Store, error) { } func createStore(store *Store) (*Store, error) { - f, err := os.Create(storePath()) + sp, err := storePath() + if err != nil { + return nil, err + } + + f, err := os.Create(sp) if err != nil { return nil, err } @@ -131,6 +141,11 @@ func createStore(store *Store) (*Store, error) { return store, nil } -func storePath() string { - return filepath.Join(os.Getenv("HOME"), ".mole.conf") +func storePath() (string, error) { + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + + return filepath.Join(home, ".mole.conf"), nil } diff --git a/storage/storage_test.go b/storage/storage_test.go index 31665bd..ad3a4ef 100644 --- a/storage/storage_test.go +++ b/storage/storage_test.go @@ -102,6 +102,7 @@ func TestMain(m *testing.M) { defer os.RemoveAll(dir) os.Setenv("HOME", dir) + os.Setenv("USERPROFILE", dir) code := m.Run() diff --git a/tunnel/config.go b/tunnel/config.go index 2187a5e..93fb5e4 100644 --- a/tunnel/config.go +++ b/tunnel/config.go @@ -19,7 +19,13 @@ type SSHConfigFile struct { // NewSSHConfigFile creates a new instance of SSHConfigFile based on the // ssh config file from $HOME/.ssh/config. func NewSSHConfigFile() (*SSHConfigFile, error) { - configPath := filepath.Join(os.Getenv("HOME"), ".ssh", "config") + home, err := os.UserHomeDir() + if err != nil { + return nil, err + } + + configPath := filepath.Join(home, ".ssh", "config") + f, err := os.Open(filepath.Clean(configPath)) if err != nil { return nil, err diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index df98688..1635885 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -72,7 +72,12 @@ func NewServer(user, address, key string) (*Server, error) { } if key == "" { - key = filepath.Join(os.Getenv("HOME"), ".ssh", "id_rsa") + home, err := os.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("could not obtain user home directory: %v", err) + } + + key = filepath.Join(home, ".ssh", "id_rsa") } pk, err := NewPemKey(key, "") @@ -285,7 +290,12 @@ func knownHostsCallback(insecure bool) (ssh.HostKeyCallback, error) { } } else { var err error - knownHostFile := filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts") + home, err := os.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("could not obtain user home directory :%v", err) + } + + knownHostFile := filepath.Join(home, ".ssh", "known_hosts") log.Debugf("known_hosts file used: %s", knownHostFile) clb, err = knownhosts.New(knownHostFile) diff --git a/tunnel/tunnel_test.go b/tunnel/tunnel_test.go index c15b80b..dda136f 100644 --- a/tunnel/tunnel_test.go +++ b/tunnel/tunnel_test.go @@ -108,7 +108,6 @@ func TestServerOptions(t *testing.T) { t.Errorf("unexpected result : expected: %s, result: %s", test.expected, s) } } - } func TestTunnelOptions(t *testing.T) { @@ -343,6 +342,7 @@ func prepareTestEnv() { } os.Setenv("HOME", home) + os.Setenv("USERPROFILE", home) } // get performs a http request using the given client appending the given