From dadfed051332e8511c3545d49142162d34232c92 Mon Sep 17 00:00:00 2001 From: Calvin Chia Date: Mon, 2 Sep 2019 15:18:54 +0800 Subject: [PATCH 01/36] Fix: redirect_uri_mismatch --- auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth.go b/auth.go index 73e0ee6..bf7293e 100644 --- a/auth.go +++ b/auth.go @@ -656,7 +656,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e content += "&client_secret=" + secrets.Installed.ClientSecret content += "&code=" + auth_code content += "&grant_type=authorization_code" - content += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" + content += "&redirect_uri=http://localhost" //************************************************************ endpoint := "https://www.googleapis.com/oauth2/v4/token" From a553d54420601c2cdc560e06da9e331c5c32a811 Mon Sep 17 00:00:00 2001 From: Calvin Chia Date: Mon, 2 Sep 2019 21:09:02 +0800 Subject: [PATCH 02/36] Use NativeClient --- winssh.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/winssh.go b/winssh.go index ee59aa1..63c1e23 100644 --- a/winssh.go +++ b/winssh.go @@ -2,7 +2,9 @@ package main import ( "fmt" - "os/exec" + + "github.com/docker/machine/libmachine/ssh" + "strconv" ) var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" @@ -28,12 +30,18 @@ func exec_winssh(params CloudShellEnv) { fmt.Println(sshUrl) } - cmd := exec.Command("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) - - err = cmd.Start() - + auth := ssh.Auth{Keys: []string{key}} + sshPortInt, err := strconv.Atoi(sshPort) + client, err := ssh.NewClient(sshUsername, sshHost, sshPortInt, &auth) if err != nil { - fmt.Println(err) + fmt.Errorf("Failed to create new client - %s", err) + return + } + + err = client.Shell() + if err != nil && err.Error() != "exit status 255" { + fmt.Errorf("Failed to request shell - %s", err) return } + } From 9b54a6ad218a856bba3a57069d54cda683725799 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Fri, 6 Sep 2019 20:51:28 +0800 Subject: [PATCH 03/36] hidemsg --- auth.go | 4 +++- cloudshell.go | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/auth.go b/auth.go index bf7293e..a0a8b81 100644 --- a/auth.go +++ b/auth.go @@ -119,7 +119,9 @@ func loadUserCredentials(filename string) (UserCredentials, error) { } func saveUserCredentials(filename string, creds UserCredentials) error { - fmt.Println("Save Credentials to:", filename) + if config.Debug == true { + fmt.Println("Save Credentials to:", filename) + } j, err := json.MarshalIndent(creds, "", " ") diff --git a/cloudshell.go b/cloudshell.go index 773a211..2a6e902 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -114,7 +114,9 @@ func cloudshell_start(accessToken string) error { // //************************************************************ - fmt.Println("Starting Cloud Shell") + if config.Debug == true { + fmt.Println("Starting Cloud Shell") + } endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default" endpoint += ":start" @@ -147,11 +149,13 @@ func cloudshell_start(accessToken string) error { return err } - fmt.Println("") - fmt.Println("************************************************************") - fmt.Println("Cloud Shell Info:") - fmt.Println(string(body)) - fmt.Println("************************************************************") + if config.Debug == true { + fmt.Println("") + fmt.Println("************************************************************") + fmt.Println("Cloud Shell Info:") + fmt.Println(string(body)) + fmt.Println("************************************************************") + } var params CloudShellEnv From ff40530279761e4397d5549f0d4cb98b10113e1e Mon Sep 17 00:00:00 2001 From: ixiumu Date: Fri, 6 Sep 2019 23:45:50 +0800 Subject: [PATCH 04/36] support vs code --- cloudshell.go | 4 +- cmdline.go | 8 ++ config.go | 1 + winssh.go | 199 +++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 200 insertions(+), 12 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 2a6e902..351fa5e 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -271,7 +271,9 @@ func call_cloud_shell(accessToken string) { } if params.State == "DISABLED" { - fmt.Println("CloudShell State:", params.State) + if config.Debug == true { + fmt.Println("CloudShell State:", params.State) + } err = cloudshell_start(accessToken) diff --git a/cmdline.go b/cmdline.go index df6cfa0..e4f9da1 100644 --- a/cmdline.go +++ b/cmdline.go @@ -115,6 +115,14 @@ func process_cmdline() { config.Command = CMD_SSH } + argString := strings.Join(args, ",") + if strings.Contains(argString, "-D,") { + config.Flags.BindAddress = args[x + 2] + + // break + return + } + case "exec": if len(args) < 2 { fmt.Println("Error: expected a remote command") diff --git a/config.go b/config.go index a377eb4..a3bba0c 100644 --- a/config.go +++ b/config.go @@ -17,6 +17,7 @@ type FlagsStruct struct { Auth bool Login string Info bool + BindAddress string } type Config struct { diff --git a/winssh.go b/winssh.go index 63c1e23..2c29db7 100644 --- a/winssh.go +++ b/winssh.go @@ -2,9 +2,14 @@ package main import ( "fmt" - - "github.com/docker/machine/libmachine/ssh" + "os/exec" + + // "github.com/docker/machine/libmachine/ssh" "strconv" + + "os" + "io" + "runtime" ) var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" @@ -30,18 +35,190 @@ func exec_winssh(params CloudShellEnv) { fmt.Println(sshUrl) } - auth := ssh.Auth{Keys: []string{key}} - sshPortInt, err := strconv.Atoi(sshPort) - client, err := ssh.NewClient(sshUsername, sshHost, sshPortInt, &auth) + sshBinaryPath, err := exec.LookPath("ssh") if err != nil { - fmt.Errorf("Failed to create new client - %s", err) - return + // fmt.Println("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) + + cmd := exec.Command("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) + err = cmd.Start() + + if err != nil { + fmt.Println(err) + return + } + + } else { + + auth := Auth{Keys: []string{key}} + sshPortInt, err := strconv.Atoi(sshPort) + + client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, config.Flags.BindAddress, &auth) + if err != nil { + fmt.Errorf("Failed to create new client - %s", err) + return + } + + err = client.Shell() + if err != nil && err.Error() != "exit status 255" { + fmt.Errorf("Failed to request shell - %s", err) + return + } } - err = client.Shell() - if err != nil && err.Error() != "exit status 255" { - fmt.Errorf("Failed to request shell - %s", err) - return +} + + + +type ExternalClient struct { + BaseArgs []string + BinaryPath string + cmd *exec.Cmd +} + +type Auth struct { + Passwords []string + Keys []string +} + +const ( + External ClientType = "external" + Native ClientType = "native" +) + +type ClientType string + +var ( + baseSSHArgs = []string{ + "-F", "/dev/null", + "-o", "ConnectionAttempts=3", // retry 3 times if SSH connection fails + "-o", "ConnectTimeout=10", // timeout after 10 seconds + "-o", "ControlMaster=no", // disable ssh multiplexing + "-o", "ControlPath=none", + "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + "-o", "PasswordAuthentication=no", + "-o", "ServerAliveInterval=60", // prevents connection to be dropped if command takes too long + "-o", "StrictHostKeyChecking=no", + "-o", "UserKnownHostsFile=/dev/null", + } + defaultClientType = External +) + +func NewExternalClient(sshBinaryPath, user, host string, port int, bind string, auth *Auth) (*ExternalClient, error) { + client := &ExternalClient{ + BinaryPath: sshBinaryPath, + } + + args := append(baseSSHArgs, fmt.Sprintf("%s@%s", user, host)) + + // If no identities are explicitly provided, also look at the identities + // offered by ssh-agent + if len(auth.Keys) > 0 { + args = append(args, "-o", "IdentitiesOnly=yes") + } + + // Specify which private keys to use to authorize the SSH request. + for _, privateKeyPath := range auth.Keys { + if privateKeyPath != "" { + // Check each private key before use it + fi, err := os.Stat(privateKeyPath) + if err != nil { + // Abort if key not accessible + return nil, err + } + if runtime.GOOS != "windows" { + mode := fi.Mode() + // log.Debugf("Using SSH private key: %s (%s)", privateKeyPath, mode) + // Private key file should have strict permissions + perm := mode.Perm() + if perm&0400 == 0 { + return nil, fmt.Errorf("'%s' is not readable", privateKeyPath) + } + if perm&0077 != 0 { + return nil, fmt.Errorf("permissions %#o for '%s' are too open", perm, privateKeyPath) + } + } + args = append(args, "-i", privateKeyPath) + } } + // Set which port to use for SSH. + args = append(args, "-p", fmt.Sprintf("%d", port)) + + if len(bind) > 0 { + args = append(args, "-D", bind) + // fmt.Println(args) + } + + client.BaseArgs = args + + return client, nil +} + +func getSSHCmd(binaryPath string, args ...string) *exec.Cmd { + return exec.Command(binaryPath, args...) +} + +func (client *ExternalClient) Output(command string) (string, error) { + args := append(client.BaseArgs, command) + cmd := getSSHCmd(client.BinaryPath, args...) + output, err := cmd.CombinedOutput() + return string(output), err +} + +func (client *ExternalClient) Shell(args ...string) error { + args = append(client.BaseArgs, args...) + cmd := getSSHCmd(client.BinaryPath, args...) + + // log.Debug(cmd) + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + return cmd.Run() +} + +func (client *ExternalClient) Start(command string) (io.ReadCloser, io.ReadCloser, error) { + args := append(client.BaseArgs, command) + cmd := getSSHCmd(client.BinaryPath, args...) + + // log.Debug(cmd) + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + if closeErr := stdout.Close(); closeErr != nil { + return nil, nil, fmt.Errorf("%s, %s", err, closeErr) + } + return nil, nil, err + } + if err := cmd.Start(); err != nil { + stdOutCloseErr := stdout.Close() + stdErrCloseErr := stderr.Close() + if stdOutCloseErr != nil || stdErrCloseErr != nil { + return nil, nil, fmt.Errorf("%s, %s, %s", + err, stdOutCloseErr, stdErrCloseErr) + } + return nil, nil, err + } + + client.cmd = cmd + return stdout, stderr, nil +} + +func (client *ExternalClient) Wait() error { + err := client.cmd.Wait() + client.cmd = nil + return err +} + +func closeConn(c io.Closer) { + err := c.Close() + if err != nil { + // log.Debugf("Error closing SSH Client: %s", err) + // fmt.Errorf("Error closing SSH Client: %s", err) + } } From 3067db720b393da3a245e5d6a3c71150b7c8f22c Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 7 Sep 2019 02:23:13 +0800 Subject: [PATCH 05/36] fix path --- auth.go | 6 +++--- config.go | 14 +++++++++++++- winssh.go | 46 +++++++++++++++++++++++----------------------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/auth.go b/auth.go index a0a8b81..45af54b 100644 --- a/auth.go +++ b/auth.go @@ -55,8 +55,8 @@ type OAuthTokens struct { } func readCredentials(filename string) ([]byte, error) { - in, err := os.Open(filename) + in, err := os.Open(config.AbsPath + "/" + filename) if err != nil { return []byte(""), err } @@ -131,7 +131,7 @@ func saveUserCredentials(filename string, creds UserCredentials) error { } // err = ioutil.WriteFile(filename + ".test", j, 0644) - err = ioutil.WriteFile(filename, j, 0644) + err = ioutil.WriteFile(config.AbsPath + "/" + filename, j, 0644) if err != nil { fmt.Println(err) @@ -425,7 +425,7 @@ func get_tokens() (string, string, error) { // fmt.Println("Login:", config.Flags.Login) if config.Flags.Auth == false { - if fileExists(SavedUserCredentials) { + if fileExists(config.AbsPath + "/" + SavedUserCredentials) { accessToken, idToken, valid := doRefresh(SavedUserCredentials) if valid == true { diff --git a/config.go b/config.go index a3bba0c..c046b5c 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "path/filepath" ) type ConfigJson struct { @@ -42,12 +43,23 @@ type Config struct { // Command line global options Flags FlagsStruct + + // ABS Path + AbsPath string } var config Config func init_config() error { - in, err := os.Open("config.json") + + path, err := filepath.Abs(filepath.Dir(os.Args[0])) + if err != nil { + fmt.Println(err) + } + + config.AbsPath = path + + in, err := os.Open( config.AbsPath + "/config.json") if err != nil { fmt.Println(err) diff --git a/winssh.go b/winssh.go index 2c29db7..81c2983 100644 --- a/winssh.go +++ b/winssh.go @@ -4,7 +4,6 @@ import ( "fmt" "os/exec" - // "github.com/docker/machine/libmachine/ssh" "strconv" "os" @@ -35,39 +34,40 @@ func exec_winssh(params CloudShellEnv) { fmt.Println(sshUrl) } - sshBinaryPath, err := exec.LookPath("ssh") + sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") if err != nil { - // fmt.Println("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) - - cmd := exec.Command("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) - err = cmd.Start() - + sshBinaryPath, err = exec.LookPath("ssh") if err != nil { - fmt.Println(err) - return + if runtime.GOOS != "windows" { + sshBinaryPath = "ssh" + } else { + sshBinaryPath = "ssh.exe" + } } + } - } else { + if config.Debug == true { + fmt.Println("Use:", sshBinaryPath) + } - auth := Auth{Keys: []string{key}} - sshPortInt, err := strconv.Atoi(sshPort) + auth := Auth{Keys: []string{key}} + sshPortInt, err := strconv.Atoi(sshPort) - client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, config.Flags.BindAddress, &auth) - if err != nil { - fmt.Errorf("Failed to create new client - %s", err) - return - } - - err = client.Shell() - if err != nil && err.Error() != "exit status 255" { - fmt.Errorf("Failed to request shell - %s", err) - return - } + client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, config.Flags.BindAddress, &auth) + if err != nil { + fmt.Errorf("Failed to create new client - %s", err) + return } + err = client.Shell() + if err != nil && err.Error() != "exit status 255" { + fmt.Errorf("Failed to request shell - %s", err) + return + } } +// "github.com/docker/machine/libmachine/ssh" type ExternalClient struct { BaseArgs []string From ce4e58c536929899bb149d36cec9b3240aee1d1b Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 7 Sep 2019 02:50:56 +0800 Subject: [PATCH 06/36] fixpath --- config.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.go b/config.go index c046b5c..ad9da35 100644 --- a/config.go +++ b/config.go @@ -52,11 +52,14 @@ var config Config func init_config() error { - path, err := filepath.Abs(filepath.Dir(os.Args[0])) + // path, err := filepath.Abs(filepath.Dir(os.Args[0])) + path, err := os.Executable() if err != nil { fmt.Println(err) } + path = filepath.Dir(path) + config.AbsPath = path in, err := os.Open( config.AbsPath + "/config.json") From ff5e66507e8658d98e31f740603ff12a8ea80278 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 7 Sep 2019 15:06:30 +0800 Subject: [PATCH 07/36] support ssh param --- cloudshell.go | 3 ++- cmdline.go | 25 +++++++++++++++++++------ config.go | 4 +++- winssh.go | 18 +++++++++++------- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 351fa5e..8f71990 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -295,7 +295,8 @@ func call_cloud_shell(accessToken string) { } if params.State == "RUNNING" { - time.Sleep(500 * time.Millisecond) + // Increase waiting time + time.Sleep(1500 * time.Millisecond) break; } } diff --git a/cmdline.go b/cmdline.go index e4f9da1..c097dfb 100644 --- a/cmdline.go +++ b/cmdline.go @@ -86,6 +86,18 @@ func process_cmdline() { continue } + // SSH args + if strings.HasPrefix(arg, "-o") { + config.sshFlags = append(config.sshFlags, "-o", os.Args[x + 1]) + x++ + continue + } + if strings.HasPrefix(arg, "-D") { + config.sshFlags = append(config.sshFlags, "-D", os.Args[x + 1]) + x++ + continue + } + args = append(args, arg) } @@ -115,13 +127,14 @@ func process_cmdline() { config.Command = CMD_SSH } - argString := strings.Join(args, ",") - if strings.Contains(argString, "-D,") { - config.Flags.BindAddress = args[x + 2] + // argString := strings.Join(args, ",") + // if strings.Contains(argString, "-D,") { + // config.Flags.BindAddress = args[x + 2] - // break - return - } + // // break + // return + // } + return case "exec": if len(args) < 2 { diff --git a/config.go b/config.go index ad9da35..bc00c4e 100644 --- a/config.go +++ b/config.go @@ -18,7 +18,6 @@ type FlagsStruct struct { Auth bool Login string Info bool - BindAddress string } type Config struct { @@ -44,6 +43,9 @@ type Config struct { // Command line global options Flags FlagsStruct + // Command line ssh options + sshFlags []string + // ABS Path AbsPath string } diff --git a/winssh.go b/winssh.go index 81c2983..8c9822c 100644 --- a/winssh.go +++ b/winssh.go @@ -11,7 +11,7 @@ import ( "runtime" ) -var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" +// var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" func exec_winssh(params CloudShellEnv) { key, err := env_get_ssh_pkey() @@ -53,7 +53,7 @@ func exec_winssh(params CloudShellEnv) { auth := Auth{Keys: []string{key}} sshPortInt, err := strconv.Atoi(sshPort) - client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, config.Flags.BindAddress, &auth) + client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, &auth, config.sshFlags) if err != nil { fmt.Errorf("Failed to create new client - %s", err) return @@ -91,7 +91,7 @@ var ( baseSSHArgs = []string{ "-F", "/dev/null", "-o", "ConnectionAttempts=3", // retry 3 times if SSH connection fails - "-o", "ConnectTimeout=10", // timeout after 10 seconds + "-o", "ConnectTimeout=30", // timeout after 10 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." @@ -103,7 +103,7 @@ var ( defaultClientType = External ) -func NewExternalClient(sshBinaryPath, user, host string, port int, bind string, auth *Auth) (*ExternalClient, error) { +func NewExternalClient(sshBinaryPath, user, host string, port int, auth *Auth, flags []string) (*ExternalClient, error) { client := &ExternalClient{ BinaryPath: sshBinaryPath, } @@ -144,13 +144,17 @@ func NewExternalClient(sshBinaryPath, user, host string, port int, bind string, // Set which port to use for SSH. args = append(args, "-p", fmt.Sprintf("%d", port)) - if len(bind) > 0 { - args = append(args, "-D", bind) + if len(flags) > 0 { + args = append(args, flags...) // fmt.Println(args) } client.BaseArgs = args + if config.Debug == true { + fmt.Println("sshArgs:", client.BaseArgs) + } + return client, nil } @@ -219,6 +223,6 @@ func closeConn(c io.Closer) { err := c.Close() if err != nil { // log.Debugf("Error closing SSH Client: %s", err) - // fmt.Errorf("Error closing SSH Client: %s", err) + fmt.Errorf("Error closing SSH Client: %s", err) } } From 7a76bbed16d9053485157d869e2501c1df972fc6 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 7 Sep 2019 21:52:22 +0800 Subject: [PATCH 08/36] add wite time --- cloudshell.go | 6 ++++-- winssh.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 8f71990..95b8b5f 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -269,12 +269,13 @@ func call_cloud_shell(accessToken string) { if config.Command == CMD_INFO { return } - if params.State == "DISABLED" { if config.Debug == true { fmt.Println("CloudShell State:", params.State) } + fmt.Println("Starting Google Cloud Shell...") + err = cloudshell_start(accessToken) if err != nil { @@ -295,8 +296,9 @@ func call_cloud_shell(accessToken string) { } if params.State == "RUNNING" { + fmt.Println("Startup successful, Waiting for SSH server to be ready...") // Increase waiting time - time.Sleep(1500 * time.Millisecond) + time.Sleep(5000 * time.Millisecond) break; } } diff --git a/winssh.go b/winssh.go index 8c9822c..98f8d9c 100644 --- a/winssh.go +++ b/winssh.go @@ -90,7 +90,7 @@ type ClientType string var ( baseSSHArgs = []string{ "-F", "/dev/null", - "-o", "ConnectionAttempts=3", // retry 3 times if SSH connection fails + "-o", "ConnectionAttempts=5", // retry 5 times if SSH connection fails "-o", "ConnectTimeout=30", // timeout after 10 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", From 8e6b3b362e984ebfda264653624ee7dc2669f64e Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 8 Sep 2019 00:08:30 +0800 Subject: [PATCH 09/36] none --- winssh.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winssh.go b/winssh.go index 98f8d9c..a34336a 100644 --- a/winssh.go +++ b/winssh.go @@ -91,12 +91,12 @@ var ( baseSSHArgs = []string{ "-F", "/dev/null", "-o", "ConnectionAttempts=5", // retry 5 times if SSH connection fails - "-o", "ConnectTimeout=30", // timeout after 10 seconds + "-o", "ConnectTimeout=10", // timeout after 10 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." "-o", "PasswordAuthentication=no", - "-o", "ServerAliveInterval=60", // prevents connection to be dropped if command takes too long + "-o", "ServerAliveInterval=30", // prevents connection to be dropped if command takes too long "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", } From 2e7fd978412fb5c8662555f94bafc70ff50c9517 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 8 Sep 2019 02:51:16 +0800 Subject: [PATCH 10/36] ping --- winssh.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/winssh.go b/winssh.go index a34336a..2a4aafe 100644 --- a/winssh.go +++ b/winssh.go @@ -6,9 +6,10 @@ import ( "strconv" - "os" "io" + "os" "runtime" + "time" ) // var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" @@ -59,6 +60,8 @@ func exec_winssh(params CloudShellEnv) { return } + // ping + go client.ServerAliveInterval() err = client.Shell() if err != nil && err.Error() != "exit status 255" { fmt.Errorf("Failed to request shell - %s", err) @@ -66,6 +69,21 @@ func exec_winssh(params CloudShellEnv) { } } +func (client *ExternalClient) ServerAliveInterval() { + for true { + time.Sleep(30000 * time.Millisecond) + args := append(client.BaseArgs, "printf", "⌚"+strconv.FormatInt(time.Now().Unix(), 10)) + cmd := getSSHCmd(client.BinaryPath, args...) + output, err := cmd.CombinedOutput() + + if err != nil { + fmt.Errorf("Ping error - %s", err) + // return + } + + fmt.Printf(string(output)) + } +} // "github.com/docker/machine/libmachine/ssh" From 2a539d72d7fa59d6716257b22fca5168c5f1091d Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 8 Sep 2019 02:52:11 +0800 Subject: [PATCH 11/36] remove ping --- winssh.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/winssh.go b/winssh.go index 2a4aafe..2b73aeb 100644 --- a/winssh.go +++ b/winssh.go @@ -9,7 +9,6 @@ import ( "io" "os" "runtime" - "time" ) // var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" @@ -60,8 +59,6 @@ func exec_winssh(params CloudShellEnv) { return } - // ping - go client.ServerAliveInterval() err = client.Shell() if err != nil && err.Error() != "exit status 255" { fmt.Errorf("Failed to request shell - %s", err) @@ -69,22 +66,6 @@ func exec_winssh(params CloudShellEnv) { } } -func (client *ExternalClient) ServerAliveInterval() { - for true { - time.Sleep(30000 * time.Millisecond) - args := append(client.BaseArgs, "printf", "⌚"+strconv.FormatInt(time.Now().Unix(), 10)) - cmd := getSSHCmd(client.BinaryPath, args...) - output, err := cmd.CombinedOutput() - - if err != nil { - fmt.Errorf("Ping error - %s", err) - // return - } - - fmt.Printf(string(output)) - } -} - // "github.com/docker/machine/libmachine/ssh" type ExternalClient struct { From 63f2a9c11e8785ff9e8e6797503daa85cfb80aca Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 9 Sep 2019 02:59:20 +0800 Subject: [PATCH 12/36] heartbeats --- scripts-remote/heartbeats | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts-remote/heartbeats diff --git a/scripts-remote/heartbeats b/scripts-remote/heartbeats new file mode 100644 index 0000000..8baf457 --- /dev/null +++ b/scripts-remote/heartbeats @@ -0,0 +1,20 @@ +#!/usr/bin/env sh + +# RUNDIR=`dirname $0` +# PIDFILE="${RUNDIR}/$0.pid" +PIDFILE="/tmp/$0.pid" + +if [ -s ${PIDFILE} ]; then + SPID=`cat ${PIDFILE}` + if [ -e /proc/${SPID}/status ]; then + exit 0 + fi + cat /dev/null > ${PIDFILE} +fi +echo $$ > ${PIDFILE} + +while sleep 360; do + if [[ -n "$(netstat | grep ":ssh " | grep ESTABLISHED)" ]]; then + http_code=$(curl -I -H "Devshell-Vm-Ip-Address:${DEVSHELL_IP_ADDRESS}" -X POST -s -w %{http_code} -o /dev/null ${DEVSHELL_SERVER_URL}/devshell/vmheartbeat); + fi +done From c7ee0a571824233e782a3cb9b67b4480f74f65ba Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 9 Sep 2019 06:31:17 +0800 Subject: [PATCH 13/36] remove config.json --- auth.go | 80 ++++++++++++++++++++------------------- config.go | 64 +++++++++++++++---------------- scripts-remote/heartbeats | 20 ---------- winssh.go | 18 +++++++++ 4 files changed, 90 insertions(+), 92 deletions(-) delete mode 100644 scripts-remote/heartbeats diff --git a/auth.go b/auth.go index 45af54b..9b7a23e 100644 --- a/auth.go +++ b/auth.go @@ -3,6 +3,7 @@ package main import ( "bufio" "context" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -12,6 +13,7 @@ import ( "os/exec" "strings" "time" + "github.com/kirinlabs/HttpRequest" "golang.org/x/oauth2/google" ) @@ -31,27 +33,27 @@ type ClientSecrets struct { } type UserCredentials struct { - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - Type string `json:"type"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + Type string `json:"type"` // The following two fields are option and exist after authentication - AccessToken string `json:"access_token"` - IDToken string `json:"id_token"` - Email string `json:"email"` - ExpiresAt int64 `json:"expires_at"` + AccessToken string `json:"access_token"` + IDToken string `json:"id_token"` + Email string `json:"email"` + ExpiresAt int64 `json:"expires_at"` } type OAuthTokens struct { - AccessToken string `json:"access_token"` - ExpiresIn int `json:"expires_in"` - RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - TokenType string `json:"token_type"` - IDToken string `json:"id_token"` - Error string `json:"error"` - ErrorDescription string `json:"error_description"` + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` + RefreshToken string `json:"refresh_token"` + Scope string `json:"scope"` + TokenType string `json:"token_type"` + IDToken string `json:"id_token"` + Error string `json:"error"` + ErrorDescription string `json:"error_description"` } func readCredentials(filename string) ([]byte, error) { @@ -71,7 +73,8 @@ func readCredentials(filename string) ([]byte, error) { func loadClientSecrets(filename string) (ClientSecrets, error) { var secrets ClientSecrets - data, err := readCredentials(filename) + // data, err := readCredentials(filename) + data, err := base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6Imt0Y2MxdlNUVFphaHRQVlc4SUE4MzN2USIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") if err != nil { return secrets, err @@ -131,7 +134,7 @@ func saveUserCredentials(filename string, creds UserCredentials) error { } // err = ioutil.WriteFile(filename + ".test", j, 0644) - err = ioutil.WriteFile(config.AbsPath + "/" + filename, j, 0644) + err = ioutil.WriteFile(config.AbsPath+"/"+filename, j, 0644) if err != nil { fmt.Println(err) @@ -192,7 +195,7 @@ func doRefresh(filename string) (string, string, bool) { // Brand new tokens are valid for 3600 seconds // For testing require 15 minutes or 900 seconds - var t time.Time = time.Unix(creds.ExpiresAt - (15 * 60), 0) + var t time.Time = time.Unix(creds.ExpiresAt-(15*60), 0) // fmt.Println(t) // fmt.Println(time.Now()) @@ -243,14 +246,14 @@ func doRefresh(filename string) (string, string, bool) { var expires_at int64 = int64(time.Now().UTC().Unix()) + int64(tokens.ExpiresIn) -/* - fmt.Println("AccessToken:", tokens.AccessToken) - fmt.Println("ExpiresIn:", tokens.ExpiresIn) - fmt.Println("ExpiresAt:", expires_at) - fmt.Println("Scope:", tokens.Scope) - fmt.Println("TokenType:", tokens.TokenType) - fmt.Println("IDToken:", tokens.IDToken) -*/ + /* + fmt.Println("AccessToken:", tokens.AccessToken) + fmt.Println("ExpiresIn:", tokens.ExpiresIn) + fmt.Println("ExpiresAt:", expires_at) + fmt.Println("Scope:", tokens.Scope) + fmt.Println("TokenType:", tokens.TokenType) + fmt.Println("IDToken:", tokens.IDToken) + */ creds.AccessToken = tokens.AccessToken creds.IDToken = tokens.IDToken @@ -352,15 +355,15 @@ func debug_displayIDToken(accessToken, idToken string) { func get_email_address(accessToken string) (string, error) { type Access_Token struct { - Azp string `json:"azp"` - Aud string `json:"aud"` - Sub string `json:"sub"` - Scope string `json:"scope"` - Exp string `json:"exp"` - Expires_in string `json:"expires_in"` - Email string `json:"email"` - Email_verified string `json:"email_verified"` - Access_type string `json:"access_type"` + Azp string `json:"azp"` + Aud string `json:"aud"` + Sub string `json:"sub"` + Scope string `json:"scope"` + Exp string `json:"exp"` + Expires_in string `json:"expires_in"` + Email string `json:"email"` + Email_verified string `json:"email_verified"` + Access_type string `json:"access_type"` } //************************************************************ @@ -436,7 +439,6 @@ func get_tokens() (string, string, error) { // debug_displayUserInfo(accessToken) // debug_displayIDToken(accessToken, idToken) - return accessToken, idToken, nil } } @@ -585,7 +587,7 @@ func get_sa_tokens() (string, string, error) { // //************************************************************ - ctx := context.Background() + ctx := context.Background() //************************************************************ // diff --git a/config.go b/config.go index bc00c4e..ebb4b76 100644 --- a/config.go +++ b/config.go @@ -1,53 +1,51 @@ package main import ( - "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" ) type ConfigJson struct { - ClientSecretsFile string `json:"client_secrets_file"` + ClientSecretsFile string `json:"client_secrets_file"` } // Global Flags type FlagsStruct struct { - Adc bool - Auth bool - Login string - Info bool + Adc bool + Auth bool + Login string + Info bool } type Config struct { // Global debug flag - Debug bool + Debug bool - UseAdcCredentials bool + UseAdcCredentials bool - ProjectId string + ProjectId string - ClientSecretsFile string + ClientSecretsFile string // Command to execute - Command int + Command int // Command "exec" - RemoteCommand string + RemoteCommand string // Commands "download" and "upload" - SrcFile string - DstFile string + SrcFile string + DstFile string // Command line global options - Flags FlagsStruct + Flags FlagsStruct // Command line ssh options - sshFlags []string + sshFlags []string // ABS Path - AbsPath string + AbsPath string } var config Config @@ -56,7 +54,7 @@ func init_config() error { // path, err := filepath.Abs(filepath.Dir(os.Args[0])) path, err := os.Executable() - if err != nil { + if err != nil { fmt.Println(err) } @@ -64,27 +62,27 @@ func init_config() error { config.AbsPath = path - in, err := os.Open( config.AbsPath + "/config.json") + // in, err := os.Open( config.AbsPath + "/config.json") - if err != nil { - fmt.Println(err) - return err - } + // if err != nil { + // fmt.Println(err) + // return err + // } - defer in.Close() + // defer in.Close() - data, err := ioutil.ReadAll(in) + // data, err := ioutil.ReadAll(in) - var configJson ConfigJson + // var configJson ConfigJson - err = json.Unmarshal(data, &configJson) + // err = json.Unmarshal(data, &configJson) - if err != nil { - fmt.Println("Error: Cannot unmarshal JSON: ", err) - return err - } + // if err != nil { + // fmt.Println("Error: Cannot unmarshal JSON: ", err) + // return err + // } - config.ClientSecretsFile = configJson.ClientSecretsFile + // config.ClientSecretsFile = configJson.ClientSecretsFile // fmt.Println("Client Secrets File:", config.ClientSecretsFile) diff --git a/scripts-remote/heartbeats b/scripts-remote/heartbeats deleted file mode 100644 index 8baf457..0000000 --- a/scripts-remote/heartbeats +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env sh - -# RUNDIR=`dirname $0` -# PIDFILE="${RUNDIR}/$0.pid" -PIDFILE="/tmp/$0.pid" - -if [ -s ${PIDFILE} ]; then - SPID=`cat ${PIDFILE}` - if [ -e /proc/${SPID}/status ]; then - exit 0 - fi - cat /dev/null > ${PIDFILE} -fi -echo $$ > ${PIDFILE} - -while sleep 360; do - if [[ -n "$(netstat | grep ":ssh " | grep ESTABLISHED)" ]]; then - http_code=$(curl -I -H "Devshell-Vm-Ip-Address:${DEVSHELL_IP_ADDRESS}" -X POST -s -w %{http_code} -o /dev/null ${DEVSHELL_SERVER_URL}/devshell/vmheartbeat); - fi -done diff --git a/winssh.go b/winssh.go index 2b73aeb..0c72dab 100644 --- a/winssh.go +++ b/winssh.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os/exec" + "time" "strconv" @@ -59,6 +60,10 @@ func exec_winssh(params CloudShellEnv) { return } + // Set heartbeats + go client.HeartBeats() + + // "curl -sSL https://raw.githubusercontent.com/ixiumu/google-cloud-shell-cli-go/patch-1/scripts-remote/heartbeats | sh & bash" err = client.Shell() if err != nil && err.Error() != "exit status 255" { fmt.Errorf("Failed to request shell - %s", err) @@ -66,6 +71,19 @@ func exec_winssh(params CloudShellEnv) { } } +func (client *ExternalClient) HeartBeats() { + for true { + time.Sleep(360 * time.Second) + args := append(client.BaseArgs, "curl -I -H \"Devshell-Vm-Ip-Address:${DEVSHELL_IP_ADDRESS}\" -X POST -s -w %{http_code} -o /dev/null ${DEVSHELL_SERVER_URL}/devshell/vmheartbeat") + cmd := getSSHCmd(client.BinaryPath, args...) + output, err := cmd.CombinedOutput() + if err != nil { + fmt.Errorf("HeartBeats error: %s", err) + } + fmt.Print("HeartBeats: ", string(output)) + } +} + // "github.com/docker/machine/libmachine/ssh" type ExternalClient struct { From c524641174c72fe7f006f46de0907c1233653ae8 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Wed, 11 Sep 2019 20:06:57 +0800 Subject: [PATCH 14/36] WINSCP --- cloudshell.go | 45 +++++++++++++++++++++++++-------------------- cmdline.go | 50 ++++++++++++++++++++++++++++++++------------------ winscp.go | 40 ++++++++++++++++++++++++++++++++++++++++ winssh.go | 4 ++-- 4 files changed, 99 insertions(+), 40 deletions(-) create mode 100644 winscp.go diff --git a/cloudshell.go b/cloudshell.go index 95b8b5f..04b95e7 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "time" + "github.com/kirinlabs/HttpRequest" ) @@ -28,17 +29,17 @@ import ( //****************************************************************************************** type CloudShellEnv struct { - Name string `json:"name"` - Id string `json:"id"` - DockerImage string `json:"dockerImage"` - State string `json:"state"` - SshUsername string `json:"sshUsername"` - SshHost string `json:"sshHost"` - SshPort int32 `json:"sshPort"` - Error struct { - Code int32 `json:"code"` - Message string `json:"message"` - Status string `json:"status"` + Name string `json:"name"` + Id string `json:"id"` + DockerImage string `json:"dockerImage"` + State string `json:"state"` + SshUsername string `json:"sshUsername"` + SshHost string `json:"sshHost"` + SshPort int32 `json:"sshPort"` + Error struct { + Code int32 `json:"code"` + Message string `json:"message"` + Status string `json:"status"` } `json:"error"` } @@ -60,8 +61,8 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{ - "Authorization": "Bearer " + accessToken, - "X-Goog-User-Project": config.ProjectId}) + "Authorization": "Bearer " + accessToken, + "X-Goog-User-Project": config.ProjectId}) //************************************************************ // @@ -128,8 +129,8 @@ func cloudshell_start(accessToken string) error { // req.Header.Set("X-Goog-User-Project", config.ProjectId) req.SetHeaders(map[string]string{ - "Authorization": "Bearer " + accessToken, - "X-Goog-User-Project": config.ProjectId}) + "Authorization": "Bearer " + accessToken, + "X-Goog-User-Project": config.ProjectId}) //************************************************************ // @@ -299,7 +300,7 @@ func call_cloud_shell(accessToken string) { fmt.Println("Startup successful, Waiting for SSH server to be ready...") // Increase waiting time time.Sleep(5000 * time.Millisecond) - break; + break } } } @@ -309,10 +310,6 @@ func call_cloud_shell(accessToken string) { return } - if config.Command == CMD_PUTTY { - exec_putty(params) - } - if config.Command == CMD_WINSSH { exec_winssh(params) } @@ -332,4 +329,12 @@ func call_cloud_shell(accessToken string) { if config.Command == CMD_UPLOAD { sftp_upload(params) } + + if config.Command == CMD_PUTTY { + exec_putty(params) + } + + if config.Command == CMD_WINSCP { + exec_winscp(params) + } } diff --git a/cmdline.go b/cmdline.go index c097dfb..99dbbb7 100644 --- a/cmdline.go +++ b/cmdline.go @@ -11,12 +11,13 @@ import ( // Commands for this program const ( CMD_INFO = iota - CMD_PUTTY CMD_WINSSH CMD_SSH CMD_EXEC CMD_UPLOAD CMD_DOWNLOAD + CMD_PUTTY + CMD_WINSCP ) func process_cmdline() { @@ -61,12 +62,12 @@ func process_cmdline() { fmt.Println("index:", x) fmt.Println("count:", len(os.Args)) - if x == len(os.Args) - 1 { + if x == len(os.Args)-1 { fmt.Println("Error: Missing email address to --login") os.Exit(1) } - config.Flags.Login = os.Args[x + 1] + config.Flags.Login = os.Args[x+1] config.Flags.Auth = true x++ continue @@ -88,15 +89,20 @@ func process_cmdline() { // SSH args if strings.HasPrefix(arg, "-o") { - config.sshFlags = append(config.sshFlags, "-o", os.Args[x + 1]) + config.sshFlags = append(config.sshFlags, "-o", os.Args[x+1]) x++ continue } if strings.HasPrefix(arg, "-D") { - config.sshFlags = append(config.sshFlags, "-D", os.Args[x + 1]) + config.sshFlags = append(config.sshFlags, "-D", os.Args[x+1]) x++ continue } + // WINSCP args + if strings.HasPrefix(arg, "/rawsettings") { + config.sshFlags = append(config.sshFlags, os.Args[x:]...) + break + } args = append(args, arg) } @@ -112,14 +118,6 @@ func process_cmdline() { case "info": config.Command = CMD_INFO - case "putty": - if isWindows() == true { - config.Command = CMD_PUTTY - } else { - fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") - os.Exit(1) - } - case "ssh": if isWindows() == true { config.Command = CMD_WINSSH @@ -143,7 +141,7 @@ func process_cmdline() { } config.Command = CMD_EXEC - config.RemoteCommand = args[x + 1] + config.RemoteCommand = args[x+1] x++ case "download": @@ -153,11 +151,11 @@ func process_cmdline() { } config.Command = CMD_DOWNLOAD - config.SrcFile = strings.ReplaceAll(args[x + 1], "\\", "/") + config.SrcFile = strings.ReplaceAll(args[x+1], "\\", "/") x++ if len(args) >= 3 { - config.DstFile = strings.ReplaceAll(args[x + 1], "\\", "/") + config.DstFile = strings.ReplaceAll(args[x+1], "\\", "/") x++ } else { _, file := path.Split(config.SrcFile) @@ -176,7 +174,7 @@ func process_cmdline() { os.Exit(1) } - path, err := filepath.Abs(args[x + 1]) + path, err := filepath.Abs(args[x+1]) if err != nil { fmt.Println(err) @@ -188,7 +186,7 @@ func process_cmdline() { x++ if len(args) >= 3 { - config.DstFile = strings.ReplaceAll(args[x + 1], "\\", "/") + config.DstFile = strings.ReplaceAll(args[x+1], "\\", "/") x++ } else { file := strings.ReplaceAll(config.SrcFile, "\\", "/") @@ -203,6 +201,22 @@ func process_cmdline() { fmt.Println("DstFile:", config.DstFile) } + case "putty": + if isWindows() == true { + config.Command = CMD_PUTTY + } else { + fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") + os.Exit(1) + } + + case "winscp": + if isWindows() == true { + config.Command = CMD_WINSCP + } else { + fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") + os.Exit(1) + } + default: if isWindows() == true { fmt.Println("Error: expected a command (info, putty, ssh, exec, upload, download)") diff --git a/winscp.go b/winscp.go new file mode 100644 index 0000000..085b05c --- /dev/null +++ b/winscp.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "os/exec" +) + +func exec_winscp(params CloudShellEnv) { + key, err := env_get_ssh_ppk() + + if err != nil { + fmt.Println("\nTip: Run the command: \"gcloud alpha cloud-shell ssh --dry-run\" to setup Cloud Shell SSH keys") + return + } + + sshUsername := params.SshUsername + sshHost := params.SshHost + sshPort := fmt.Sprint(params.SshPort) + sshUrl := "sftp://" + sshUsername + "@" + sshHost + ":" + sshPort + + args := append([]string{"/ini=nul", "/privatekey=" + key, "/hostkey=*", sshUrl}, config.sshFlags...) + + if config.Debug == true { + fmt.Println(key) + fmt.Println(sshUsername) + fmt.Println(sshHost) + fmt.Println(sshPort) + fmt.Println(sshUrl) + fmt.Println(args) + } + + cmd := exec.Command("winscp.exe", args...) + + err = cmd.Start() + + if err != nil { + fmt.Println(err) + return + } +} diff --git a/winssh.go b/winssh.go index 0c72dab..32196c8 100644 --- a/winssh.go +++ b/winssh.go @@ -106,9 +106,9 @@ type ClientType string var ( baseSSHArgs = []string{ - "-F", "/dev/null", + // "-F", "/dev/null", // disable load ~/.ssh/config "-o", "ConnectionAttempts=5", // retry 5 times if SSH connection fails - "-o", "ConnectTimeout=10", // timeout after 10 seconds + // "-o", "ConnectTimeout=5", // timeout after 5 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." From b55dc7befd70dd1a182c9bc41a5b7635403819bd Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 14 Sep 2019 17:19:16 +0800 Subject: [PATCH 15/36] add self proxy --- cloudshell.go | 35 ++++++++++++-- cmdline.go | 8 +++ config.go | 3 ++ winssh.go | 131 ++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 167 insertions(+), 10 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 04b95e7..7239a50 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "net" "time" "github.com/kirinlabs/HttpRequest" @@ -136,7 +137,7 @@ func cloudshell_start(accessToken string) error { // //************************************************************ - res, err := req.Post(endpoint) + res, err := req.JSON().Post(endpoint, "{\"accessToken\": \""+accessToken+"\"}") if err != nil { fmt.Println("Error: ", err) @@ -270,12 +271,12 @@ func call_cloud_shell(accessToken string) { if config.Command == CMD_INFO { return } - if params.State == "DISABLED" { + if params.State != "DISABLED" { if config.Debug == true { fmt.Println("CloudShell State:", params.State) } - fmt.Println("Starting Google Cloud Shell...") + fmt.Println("Starting your Cloud Shell machine...") err = cloudshell_start(accessToken) @@ -297,12 +298,36 @@ func call_cloud_shell(accessToken string) { } if params.State == "RUNNING" { - fmt.Println("Startup successful, Waiting for SSH server to be ready...") + fmt.Println("Waiting for your Cloud Shell machine to start...") // Increase waiting time - time.Sleep(5000 * time.Millisecond) + // time.Sleep(5000 * time.Millisecond) + break } } + + // waiting + host := params.SshHost + port := fmt.Sprint(params.SshPort) + + for x := 0; x < 60; x++ { + time.Sleep(500 * time.Millisecond) + + timeout := time.Second + conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) + if err != nil { + fmt.Println("Connecting error:", err) + return + } + if conn != nil { + defer conn.Close() + if config.Debug == true { + fmt.Println("Opened", net.JoinHostPort(host, port)) + } + break + } + } + } if params.State != "RUNNING" { diff --git a/cmdline.go b/cmdline.go index 99dbbb7..7cc3580 100644 --- a/cmdline.go +++ b/cmdline.go @@ -103,6 +103,14 @@ func process_cmdline() { config.sshFlags = append(config.sshFlags, os.Args[x:]...) break } + if arg == "-v2ray" || arg == "--v2" { + config.Proxy = "v2ray" + continue + } + if arg == "-shadowsocks" || arg == "--ss" { + config.Proxy = "shadowsocks" + continue + } args = append(args, arg) } diff --git a/config.go b/config.go index ebb4b76..6c46fed 100644 --- a/config.go +++ b/config.go @@ -46,6 +46,9 @@ type Config struct { // ABS Path AbsPath string + + // proxy + Proxy string } var config Config diff --git a/winssh.go b/winssh.go index 32196c8..31cd1a2 100644 --- a/winssh.go +++ b/winssh.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "net/http" "os/exec" "time" @@ -13,6 +14,7 @@ import ( ) // var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" +var proxy *exec.Cmd func exec_winssh(params CloudShellEnv) { key, err := env_get_ssh_pkey() @@ -35,6 +37,22 @@ func exec_winssh(params CloudShellEnv) { fmt.Println(sshUrl) } + // go ShadowSocks(sshHost, sshPort) + + if config.Proxy == "v2ray" { + fmt.Println("Proxy: V2ray") + + V2ray(sshHost, sshPort) + // time.Sleep(2 * time.Second) + CheckPort(sshHost, sshPort) + } else if config.Proxy == "shadowsocks" { + fmt.Println("Proxy: V2ray") + + ShadowSocks(sshHost, sshPort) + // time.Sleep(2 * time.Second) + CheckPort(sshHost, sshPort) + } + sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") if err != nil { sshBinaryPath, err = exec.LookPath("ssh") @@ -56,7 +74,7 @@ func exec_winssh(params CloudShellEnv) { client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, &auth, config.sshFlags) if err != nil { - fmt.Errorf("Failed to create new client - %s", err) + fmt.Println("Failed to create new client - ", err) return } @@ -66,9 +84,112 @@ func exec_winssh(params CloudShellEnv) { // "curl -sSL https://raw.githubusercontent.com/ixiumu/google-cloud-shell-cli-go/patch-1/scripts-remote/heartbeats | sh & bash" err = client.Shell() if err != nil && err.Error() != "exit status 255" { - fmt.Errorf("Failed to request shell - %s", err) + fmt.Println("Failed to request shell - ", err) + // return + } + + if config.Proxy != "" { + proxy.Process.Kill() + } + +} + +func V2ray(sshHost string, sshPort string) { + ssBinaryPath, err := exec.LookPath(config.AbsPath + "/v2ray/v2ray.exe") + if err != nil { + fmt.Println("Failed to create proxy client - ", err) + return + } + + url := "http://" + sshHost + ":" + sshPort + "/api/v2ray.json" + + proxy = exec.Command(ssBinaryPath, "-config", url) + + err = proxy.Start() + if err != nil { + fmt.Println("Failed to create proxy client - ", err) + return + } + + if config.Debug == true { + fmt.Println("Proxy Config:", url) + } + + // config.sshFlags = append(config.sshFlags, "-o", "ProxyCommand=\"C:\\Program Files\\Git\\mingw64\\bin\\connect.exe -S 127.0.0.1:8022 %h %p\"") + + config.sshFlags = append(config.sshFlags, "-o", "ProxyCommand=connect.exe -S 127.0.0.1:8022 %h %p") + + // https://stackoverflow.com/questions/34730941/ensure-executables-called-in-go-process-get-killed-when-process-is-killed + +} + +func ShadowSocks(sshHost string, sshPort string) { + // ss-local -s 1.1.1.1 -p 6000 -k 7758521 -m rc4-md5 -l 8022 --plugin v2ray-plugin --plugin-opts "tls;path=/api/shadowsocks/;host=localhost" + ssArgs := []string{"-m", "rc4-md5", "-l", "8022", "--plugin-opts", "tls;path=/api/shadowsocks/;host=localhost"} + + ssArgs = append(ssArgs, "-k", "7758521") + ssArgs = append(ssArgs, "-s", sshHost) + ssArgs = append(ssArgs, "-p", sshPort) + + ssBinaryPath, err := exec.LookPath(config.AbsPath + "/shadowsocks-libev/ss-local.exe") + + // fmt.Println(ssBinaryPath) + + if err != nil { + fmt.Println("Failed to create proxy client - ", err) + return + } + + ssPluginBinaryPath, err := exec.LookPath(config.AbsPath + "/shadowsocks-libev/v2ray-plugin.exe") + if err != nil { + fmt.Println("Failed to find proxy plugin - ", err) return } + + ssArgs = append(ssArgs, "--plugin", ssPluginBinaryPath) + + proxy = exec.Command(ssBinaryPath, ssArgs...) + // output, err := proxy.CombinedOutput() + // fmt.Println(string(output)) + // return + err = proxy.Start() + if err != nil { + fmt.Println("Failed to create proxy client - ", err) + return + } + + if config.Debug == true { + fmt.Println("Proxy:", ssArgs) + } + + config.sshFlags = append(config.sshFlags, "-o", "ProxyCommand=connect.exe -S 127.0.0.1:8022 %h %p") + +} + +func CheckPort(sshHost string, sshPort string) { + for x := 0; x < 60; x++ { + time.Sleep(500 * time.Millisecond) + + resp, err := http.Get("http://" + sshHost + ":" + sshPort + "/api/v2ray.json") + + if err != nil { + return + } + + defer resp.Body.Close() + + // if resp.StatusCode != http.StatusOK { + // // fmt.Println("Error: status code",resp.StatusCode) + // return + // } + + if resp.StatusCode == 200 { + if config.Debug == true { + fmt.Println("CheckPort: status code", resp.StatusCode) + } + break + } + } } func (client *ExternalClient) HeartBeats() { @@ -78,7 +199,7 @@ func (client *ExternalClient) HeartBeats() { cmd := getSSHCmd(client.BinaryPath, args...) output, err := cmd.CombinedOutput() if err != nil { - fmt.Errorf("HeartBeats error: %s", err) + fmt.Println("HeartBeats error: ", err) } fmt.Print("HeartBeats: ", string(output)) } @@ -111,7 +232,7 @@ var ( // "-o", "ConnectTimeout=5", // timeout after 5 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", - "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + // "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." "-o", "PasswordAuthentication=no", "-o", "ServerAliveInterval=30", // prevents connection to be dropped if command takes too long "-o", "StrictHostKeyChecking=no", @@ -240,6 +361,6 @@ func closeConn(c io.Closer) { err := c.Close() if err != nil { // log.Debugf("Error closing SSH Client: %s", err) - fmt.Errorf("Error closing SSH Client: %s", err) + fmt.Println("Error closing SSH Client: ", err) } } From 29ed3359388624efb99e22efd05a0927a230d05e Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sat, 14 Sep 2019 17:35:42 +0800 Subject: [PATCH 16/36] fix --- cloudshell.go | 10 ++++++---- winssh.go | 46 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 7239a50..8ef3083 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -117,7 +117,7 @@ func cloudshell_start(accessToken string) error { //************************************************************ if config.Debug == true { - fmt.Println("Starting Cloud Shell") + fmt.Println("Request users.environment.start") } endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default" @@ -271,7 +271,7 @@ func call_cloud_shell(accessToken string) { if config.Command == CMD_INFO { return } - if params.State != "DISABLED" { + if params.State == "DISABLED" { if config.Debug == true { fmt.Println("CloudShell State:", params.State) } @@ -316,8 +316,10 @@ func call_cloud_shell(accessToken string) { timeout := time.Second conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) if err != nil { - fmt.Println("Connecting error:", err) - return + if config.Debug == true { + fmt.Println("Connecting error:", err) + } + continue } if conn != nil { defer conn.Close() diff --git a/winssh.go b/winssh.go index 31cd1a2..35689ce 100644 --- a/winssh.go +++ b/winssh.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "net" "net/http" "os/exec" "time" @@ -40,17 +41,20 @@ func exec_winssh(params CloudShellEnv) { // go ShadowSocks(sshHost, sshPort) if config.Proxy == "v2ray" { - fmt.Println("Proxy: V2ray") + if config.Debug == true { + fmt.Println("Proxy: V2ray") + } + CheckUrlConfig(sshHost, sshPort) V2ray(sshHost, sshPort) - // time.Sleep(2 * time.Second) - CheckPort(sshHost, sshPort) + CheckPort("127.0.0.1", "8022") } else if config.Proxy == "shadowsocks" { - fmt.Println("Proxy: V2ray") + if config.Debug == true { + fmt.Println("Proxy: shadowsocks") + } ShadowSocks(sshHost, sshPort) - // time.Sleep(2 * time.Second) - CheckPort(sshHost, sshPort) + CheckPort("127.0.0.1", "8022") } sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") @@ -166,7 +170,7 @@ func ShadowSocks(sshHost string, sshPort string) { } -func CheckPort(sshHost string, sshPort string) { +func CheckUrlConfig(sshHost string, sshPort string) { for x := 0; x < 60; x++ { time.Sleep(500 * time.Millisecond) @@ -179,8 +183,10 @@ func CheckPort(sshHost string, sshPort string) { defer resp.Body.Close() // if resp.StatusCode != http.StatusOK { - // // fmt.Println("Error: status code",resp.StatusCode) - // return + // if config.Debug == true { + // fmt.Println("Error: status code", resp.StatusCode) + // } + // continue // } if resp.StatusCode == 200 { @@ -192,6 +198,28 @@ func CheckPort(sshHost string, sshPort string) { } } +func CheckPort(host string, port string) { + for x := 0; x < 60; x++ { + time.Sleep(500 * time.Millisecond) + + timeout := time.Second + conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) + if err != nil { + if config.Debug == true { + fmt.Println("Connecting error:", err) + } + continue + } + if conn != nil { + defer conn.Close() + if config.Debug == true { + fmt.Println("Opened", net.JoinHostPort(host, port)) + } + break + } + } +} + func (client *ExternalClient) HeartBeats() { for true { time.Sleep(360 * time.Second) From 7a3f18bc1702ae33af99301623bd195b9f4a713c Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 15 Sep 2019 02:28:22 +0800 Subject: [PATCH 17/36] urlfetch --- auth.go | 20 ++++++++++++++++++++ cloudshell.go | 8 ++++++++ cmdline.go | 6 ++++++ config.go | 3 +++ 4 files changed, 37 insertions(+) diff --git a/auth.go b/auth.go index 9b7a23e..d4700d7 100644 --- a/auth.go +++ b/auth.go @@ -182,6 +182,10 @@ func debug_PrintUserCredentials(creds UserCredentials) { func doRefresh(filename string) (string, string, bool) { endpoint := "https://www.googleapis.com/oauth2/v4/token" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + creds, err := loadUserCredentials(filename) if err != nil { @@ -282,6 +286,10 @@ func doRefresh(filename string) (string, string, bool) { func debug_displayAccessToken(accessToken string) { endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) @@ -306,6 +314,10 @@ func debug_displayAccessToken(accessToken string) { func debug_displayUserInfo(accessToken string) { endpoint := "https://www.googleapis.com/oauth2/v3/userinfo" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) @@ -332,6 +344,10 @@ func debug_displayIDToken(accessToken, idToken string) { endpoint += "?id_token=" + idToken + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) @@ -372,6 +388,10 @@ func get_email_address(accessToken string) (string, error) { endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) diff --git a/cloudshell.go b/cloudshell.go index 8ef3083..38527fb 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -59,6 +59,10 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default" endpoint += "?alt=json" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() req.SetHeaders(map[string]string{ @@ -124,6 +128,10 @@ func cloudshell_start(accessToken string) error { endpoint += ":start" endpoint += "?alt=json" + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + req := HttpRequest.NewRequest() // req.Header.Set("Authorization", "Bearer " + accessToken) diff --git a/cmdline.go b/cmdline.go index 7cc3580..c3db9d8 100644 --- a/cmdline.go +++ b/cmdline.go @@ -103,6 +103,7 @@ func process_cmdline() { config.sshFlags = append(config.sshFlags, os.Args[x:]...) break } + // Proxy if arg == "-v2ray" || arg == "--v2" { config.Proxy = "v2ray" continue @@ -111,6 +112,11 @@ func process_cmdline() { config.Proxy = "shadowsocks" continue } + if arg == "-urlfetch" || arg == "--urlfetch" { + config.UrlFetch = os.Args[x+1] + x++ + continue + } args = append(args, arg) } diff --git a/config.go b/config.go index 6c46fed..412ed6d 100644 --- a/config.go +++ b/config.go @@ -49,6 +49,9 @@ type Config struct { // proxy Proxy string + + // api proxy + UrlFetch string } var config Config From 85f92b24cb00f8d69dd3ae0af27292771f6c6e1e Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 15 Sep 2019 02:38:44 +0800 Subject: [PATCH 18/36] support --proxy --- cmdline.go | 5 +++++ winssh.go | 2 ++ 2 files changed, 7 insertions(+) diff --git a/cmdline.go b/cmdline.go index c3db9d8..b686d98 100644 --- a/cmdline.go +++ b/cmdline.go @@ -104,6 +104,11 @@ func process_cmdline() { break } // Proxy + if arg == "-proxy" || arg == "--proxy" { + config.Proxy = os.Args[x+1] + x++ + continue + } if arg == "-v2ray" || arg == "--v2" { config.Proxy = "v2ray" continue diff --git a/winssh.go b/winssh.go index 35689ce..462da96 100644 --- a/winssh.go +++ b/winssh.go @@ -55,6 +55,8 @@ func exec_winssh(params CloudShellEnv) { ShadowSocks(sshHost, sshPort) CheckPort("127.0.0.1", "8022") + } else if config.Proxy != "" { + config.sshFlags = append(config.sshFlags, "-o", "ProxyCommand=connect.exe -S "+config.Proxy+" %h %p") } sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") From aa7607c2add1bb2babd1852c0eca4d021d8a2a7c Mon Sep 17 00:00:00 2001 From: ixiumu Date: Sun, 15 Sep 2019 15:38:24 +0800 Subject: [PATCH 19/36] fix --- winssh.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/winssh.go b/winssh.go index 462da96..204cb30 100644 --- a/winssh.go +++ b/winssh.go @@ -223,15 +223,28 @@ func CheckPort(host string, port string) { } func (client *ExternalClient) HeartBeats() { + + time.Sleep(10 * time.Second) + + if config.Debug == true { + fmt.Print("Start Send HeartBeats") + } + for true { - time.Sleep(360 * time.Second) args := append(client.BaseArgs, "curl -I -H \"Devshell-Vm-Ip-Address:${DEVSHELL_IP_ADDRESS}\" -X POST -s -w %{http_code} -o /dev/null ${DEVSHELL_SERVER_URL}/devshell/vmheartbeat") + cmd := getSSHCmd(client.BinaryPath, args...) output, err := cmd.CombinedOutput() + if err != nil { - fmt.Println("HeartBeats error: ", err) + fmt.Print("HeartBeats error: ", err) + } + + if config.Debug == true { + fmt.Print("HeartBeats: ", string(output)) } - fmt.Print("HeartBeats: ", string(output)) + + time.Sleep(360 * time.Second) } } @@ -262,7 +275,7 @@ var ( // "-o", "ConnectTimeout=5", // timeout after 5 seconds "-o", "ControlMaster=no", // disable ssh multiplexing "-o", "ControlPath=none", - // "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." + "-o", "LogLevel=quiet", // suppress "Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts." "-o", "PasswordAuthentication=no", "-o", "ServerAliveInterval=30", // prevents connection to be dropped if command takes too long "-o", "StrictHostKeyChecking=no", From 315ecfdcb780155374f5d6416b07c6748151be1b Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 01:04:18 +0800 Subject: [PATCH 20/36] vscode_ssh.cmd --- scripts-windows/vscode_ssh.cmd | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 scripts-windows/vscode_ssh.cmd diff --git a/scripts-windows/vscode_ssh.cmd b/scripts-windows/vscode_ssh.cmd new file mode 100644 index 0000000..2a05a7b --- /dev/null +++ b/scripts-windows/vscode_ssh.cmd @@ -0,0 +1,15 @@ +@echo off +cd %~dp0 +if "%1"=="" ( + type %UserProfile%\.ssh\config | find /i "host " + exit /b +) +set vscode_host="%3" +set port="%2" +if "%vscode_host:cloudshell=%"=="%vscode_host%" ( + ssh %* +) else ( + REM cloudshell.exe ssh -D %port% --urlfetch https://****/urlfetch/ --v2ray + cloudshell.exe ssh -D %port% --proxy 127.0.0.1:1080 --debug + REM cloudshell.exe ssh -D %port% -o LocalForward="127.0.0.1:22080 127.0.0.1:22080" -o ProxyCommand="C:\Program Files\Git\mingw64\bin\connect.exe -S 127.0.0.1:1080 %%h %%p" +) \ No newline at end of file From 7af141451888a17227ccdae165170e7fb0620d23 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 01:22:18 +0800 Subject: [PATCH 21/36] onlay command line auth --- auth.go | 163 ++--------------------------------- cloudshell.go | 14 +-- cmdline.go | 30 ++++++- main.go | 6 ++ scripts-windows/setup_go.bat | 1 + webserver.py | 110 ----------------------- winssh.go | 30 +++++++ 7 files changed, 72 insertions(+), 282 deletions(-) delete mode 100644 webserver.py diff --git a/auth.go b/auth.go index d4700d7..889ea0c 100644 --- a/auth.go +++ b/auth.go @@ -8,9 +8,7 @@ import ( "errors" "fmt" "io/ioutil" - "log" "os" - "os/exec" "strings" "time" @@ -74,7 +72,7 @@ func loadClientSecrets(filename string) (ClientSecrets, error) { var secrets ClientSecrets // data, err := readCredentials(filename) - data, err := base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6Imt0Y2MxdlNUVFphaHRQVlc4SUE4MzN2USIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") + data, err := base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6ImJEUEN4eTl3LTlac0ZoQ2hpX243Yk5ERyIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") if err != nil { return secrets, err @@ -440,10 +438,6 @@ func get_tokens() (string, string, error) { return get_sa_tokens() } - //************************************************************ - // - //************************************************************ - // fmt.Println("Auth:", config.Flags.Auth) // fmt.Println("Login:", config.Flags.Login) @@ -475,22 +469,6 @@ func get_tokens() (string, string, error) { return "", "", err } - //************************************************************ - // If we are running under Linux and the program xdg-open - // is not present, then we probably are not running under - // a desktop. An example would be Windows Linux Subsystem (WSL) - //************************************************************ - - var flag_desktop bool = true - - if isWindows() == false { - _, err := exec.LookPath("dxg-open") - - if err != nil { - flag_desktop = false - } - } - //************************************************************ // Build the authenticate URL //************************************************************ @@ -504,115 +482,17 @@ func get_tokens() (string, string, error) { url += "&login_hint=" + config.Flags.Login } - if isWindows() == true { - url += "&redirect_uri=http://localhost:9000" - } else { - if flag_desktop == true { - url += "&redirect_uri=http://localhost:9000" - } else { - url += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" - - return manualAuthentication(secrets, url) - } - } - - //************************************************************ - // The following code requires Python - //************************************************************ - - python_path, err := exec.LookPath("python3") - - if err != nil { - python_path, err = exec.LookPath("python") - - if err != nil { - fmt.Println("Error: Cannot find the python program to launch the internal web server for authentication") - return "", "", err - } - } - - if config.Debug == true { - fmt.Println("Python Path:", python_path) - } - - //************************************************************ - - if isWindows() == true { - chrome, err := FindChromeBrowser() - - var cmd *exec.Cmd - - if err == nil { - cmd = exec.Command(chrome, url) - - err = cmd.Start() - } else { - cmd = exec.Command("rundll32", "url.dll,FileProtocolHandler", url) - } + url += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" - err = cmd.Start() - } else { - // This requires that Linux has a desktop - err = exec.Command("xdg-open", url).Start() - } - - if err != nil { - fmt.Println(err) - return "", "", err - } - - fmt.Println("Chrome running") - - //************************************************************ - // Start the web server - // - // FIX: This is coded in Python. - //************************************************************ - - fmt.Println("Web server starting") - - var out []byte - - out, err = exec.Command(python_path, "webserver.py").Output() - - if err != nil { - fmt.Println("Error: Web server failed to start") - fmt.Println(err) - return "", "", err - } - - if len(out) == 0 { - fmt.Println("************************************************************") - fmt.Println(out) - log.Fatal("Error: Missing OAuth2 Code") - } - - if config.Debug == true { - fmt.Println("OAuth2 Code:", string(out)) - } - - auth_code := string(out) - - return processAuthCode(secrets, auth_code) + return manualAuthentication(secrets, url) } func get_sa_tokens() (string, string, error) { - //************************************************************ - // - //************************************************************ scope := "https://www.googleapis.com/auth/cloud-platform" - //************************************************************ - // - //************************************************************ - ctx := context.Background() - //************************************************************ - // - //************************************************************ - creds, err := google.FindDefaultCredentials(ctx, scope) if err != nil { @@ -620,10 +500,6 @@ func get_sa_tokens() (string, string, error) { return "", "", err } - //************************************************************ - // - //************************************************************ - token, err := creds.TokenSource.Token() if err != nil { @@ -631,39 +507,12 @@ func get_sa_tokens() (string, string, error) { return "", "", err } - //************************************************************ - // - //************************************************************ - return token.AccessToken, "", nil } -func FindChromeBrowser() (string, error) { - // Web browser to launch to authenticate - // This path is valid for Windows x64 only - // FIX - Test for Windows x86 - var chrome1 = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" - var chrome2 = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" - - if fileExists(chrome1) { - return chrome1, nil - } - - if fileExists(chrome2) { - return chrome2, nil - } - - err := errors.New("Cannot find Google Chrome Browser") - - return "", err -} - func manualAuthentication(secrets ClientSecrets, url string) (string, string, error) { - fmt.Println("Go to the following link in your browser:") - fmt.Println() - fmt.Println(url) - fmt.Println() - fmt.Print("Enter verification code: ") + + fmt.Print("Go to the following link in your browser:\n\n" + url + "\n\nEnter verification code: ") reader := bufio.NewReader(os.Stdin) @@ -680,7 +529,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e content += "&client_secret=" + secrets.Installed.ClientSecret content += "&code=" + auth_code content += "&grant_type=authorization_code" - content += "&redirect_uri=http://localhost" + content += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" //************************************************************ endpoint := "https://www.googleapis.com/oauth2/v4/token" diff --git a/cloudshell.go b/cloudshell.go index 38527fb..7a016ff 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -50,9 +50,6 @@ type CloudShellEnv struct { //****************************************************************************************** func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShellEnv, error) { - //************************************************************ - // - //************************************************************ var params CloudShellEnv @@ -88,11 +85,8 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell } if flag_info == true { - fmt.Println("") - fmt.Println("************************************************************") fmt.Println("Cloud Shell Info:") fmt.Println(string(body)) - fmt.Println("************************************************************") } err = json.Unmarshal(body, ¶ms) @@ -134,17 +128,10 @@ func cloudshell_start(accessToken string) error { req := HttpRequest.NewRequest() - // req.Header.Set("Authorization", "Bearer " + accessToken) - // req.Header.Set("X-Goog-User-Project", config.ProjectId) - req.SetHeaders(map[string]string{ "Authorization": "Bearer " + accessToken, "X-Goog-User-Project": config.ProjectId}) - //************************************************************ - // - //************************************************************ - res, err := req.JSON().Post(endpoint, "{\"accessToken\": \""+accessToken+"\"}") if err != nil { @@ -178,6 +165,7 @@ func cloudshell_start(accessToken string) error { if params.Error.Code != 0 { err = errors.New(params.Error.Message) + fmt.Println("Error Code:", params.Error.Code) fmt.Println(err) return err } diff --git a/cmdline.go b/cmdline.go index b686d98..00df862 100644 --- a/cmdline.go +++ b/cmdline.go @@ -13,6 +13,7 @@ const ( CMD_INFO = iota CMD_WINSSH CMD_SSH + CMD_SSH_VSCODE CMD_EXEC CMD_UPLOAD CMD_DOWNLOAD @@ -88,16 +89,38 @@ func process_cmdline() { } // SSH args - if strings.HasPrefix(arg, "-o") { + if arg == "-o" { config.sshFlags = append(config.sshFlags, "-o", os.Args[x+1]) x++ continue } - if strings.HasPrefix(arg, "-D") { + if arg == "-D" { + // support vs code + if x == 1 && len(os.Args) == 5 && os.Args[4] == "bash" { + + if os.Args[3] == "cloudshell" { + config.Debug = true + + if isWindows() == true { + config.Command = CMD_WINSSH + } else { + config.Command = CMD_SSH + } + } else { + config.Command = CMD_SSH_VSCODE + config.sshFlags = append(config.sshFlags, "-D", os.Args[2], os.Args[3]) + break + } + } + config.sshFlags = append(config.sshFlags, "-D", os.Args[x+1]) x++ continue } + if arg == "-V" { + fmt.Println("OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5") + os.Exit(0) + } // WINSCP args if strings.HasPrefix(arg, "/rawsettings") { config.sshFlags = append(config.sshFlags, os.Args[x:]...) @@ -237,6 +260,9 @@ func process_cmdline() { } default: + if config.Command != 0 { + return + } if isWindows() == true { fmt.Println("Error: expected a command (info, putty, ssh, exec, upload, download)") } else { diff --git a/main.go b/main.go index b32182e..774ceca 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,12 @@ func main() { os.Exit(1) } + // vscode + if config.Command == CMD_SSH_VSCODE { + exec_vscode_ssh() + os.Exit(1) + } + //************************************************************ // //************************************************************ diff --git a/scripts-windows/setup_go.bat b/scripts-windows/setup_go.bat index 0e322e0..9551010 100644 --- a/scripts-windows/setup_go.bat +++ b/scripts-windows/setup_go.bat @@ -1,4 +1,5 @@ go get github.com/kirinlabs/HttpRequest go get github.com/pkg/sftp +go get github.com/gookit/color go get golang.org/x/crypto/ssh go get golang.org/x/oauth2/google diff --git a/webserver.py b/webserver.py deleted file mode 100644 index 837b458..0000000 --- a/webserver.py +++ /dev/null @@ -1,110 +0,0 @@ -""" -This program implements a webserver for receiving the OAuth 2.0 code - -This is a single shot web server. Only one request is processed and then the -web server exits. -""" - -import sys -from http.server import BaseHTTPRequestHandler, HTTPServer -from urllib.parse import urlparse, parse_qsl - -# The listening port can be anything but must be available -web_port = int(9000) - -flag_continue = True - -class ProcessRequests(BaseHTTPRequestHandler): - """ - Web server callback function to process GET, POST, etc. - """ - - def log_message(self, format, *args): - """ - This function noops the log message for requests received. - """ - return - - def do_GET(self): - """ - Process the web server GET request. - """ - - rcvd_code = None - - # - # process the query parameters. We are looking for a "code". - # - - sys.stderr.write('Query: {}\n'.format(urlparse(self.path).query)) - - items = parse_qsl(urlparse(self.path).query) - - for item in items: - if 'code' in item: - global flag_continue - - sys.stderr.write('Found item: {} = {}\n'.format(item[0], item[1])) - sys.stdout.write(item[1]) - rcvd_code = item[1] - - flag_continue = False - - if 'error' in item: - sys.stderr.write('Found item: {} = {}\n'.format(item[0], item[1])) - sys.stderr.write(item[1] + '\n') - - if rcvd_code is None: - sys.stderr.write('Error: Invalid request: {}\n'.format(self.path)) - sys.stderr.write('Error: Request does not include query param "code=value"') - self.send_response(404) - self.send_header('Content-type', 'text/html') - self.end_headers() - return - - # Notice that this url is 'https' which must be specified for the redirect - # FIX - self.send_response(200) - self.send_header('Content-type', 'text/html') - self.end_headers() - - html = b""" -" -Please return to the app.") - """ - self.wfile.write(html) - -def run_local_webserver(server_class=HTTPServer, handler_class=ProcessRequests, port=web_port): - """ - This function implements a web server. Once the web browser calls this server - with a 'code', the server prints the code and exits. - """ - - server_address = ('', port) - - try: - httpd = server_class(server_address, handler_class) - except: - e_type = sys.exc_info()[0] - e_msg = sys.exc_info()[1] - sys.stderr.write('\n') - sys.stderr.write('****************************************\n') - sys.stderr.write('Error: Cannot start local web server on port {}\n'. format(web_port)) - sys.stderr.write('Error: %s\n', e_type) - sys.stderr.write('Error: %s\n', e_msg) - exit(1) - - # sys.stderr.write('Starting httpd...\n') - - sys.stderr.write('Listening on port {} ...\n'.format(web_port)) - while flag_continue: - httpd.handle_request() - - # All done. - -if __name__ == "__main__": - # print('Hello world from Python') - - run_local_webserver() - - exit(0) diff --git a/winssh.go b/winssh.go index 204cb30..8a77815 100644 --- a/winssh.go +++ b/winssh.go @@ -100,6 +100,36 @@ func exec_winssh(params CloudShellEnv) { } +func exec_vscode_ssh() { + + sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") + if err != nil { + sshBinaryPath, err = exec.LookPath("ssh") + if err != nil { + if runtime.GOOS != "windows" { + sshBinaryPath = "ssh" + } else { + sshBinaryPath = "ssh.exe" + } + } + } + + cmd := exec.Command(sshBinaryPath, config.sshFlags...) + + // log.Debug(cmd) + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + err = cmd.Run() + if err != nil && err.Error() != "exit status 255" { + fmt.Println("Failed to request shell - ", err) + // return + } + +} + func V2ray(sshHost string, sshPort string) { ssBinaryPath, err := exec.LookPath(config.AbsPath + "/v2ray/v2ray.exe") if err != nil { From f28dad12ceda1f3c4559826638d29775b97dcf91 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 02:12:42 +0800 Subject: [PATCH 22/36] add config.json settings --- auth.go | 10 ++++++++-- cloudshell.go | 1 + config.go | 50 ++++++++++++++++++++++++++++++++++---------------- config.json | 8 ++++++-- winssh.go | 4 ++-- 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/auth.go b/auth.go index 889ea0c..859a82d 100644 --- a/auth.go +++ b/auth.go @@ -70,9 +70,15 @@ func readCredentials(filename string) ([]byte, error) { func loadClientSecrets(filename string) (ClientSecrets, error) { var secrets ClientSecrets + var data []byte + var err error - // data, err := readCredentials(filename) - data, err := base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6ImJEUEN4eTl3LTlac0ZoQ2hpX243Yk5ERyIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") + if filename == "" { + data, err = readCredentials(filename) + } else { + // + data, err = base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6ImJEUEN4eTl3LTlac0ZoQ2hpX243Yk5ERyIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") + } if err != nil { return secrets, err diff --git a/cloudshell.go b/cloudshell.go index 7a016ff..063de99 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -334,6 +334,7 @@ func call_cloud_shell(accessToken string) { } if config.Command == CMD_WINSSH { + fmt.Println("Your Cloud Shell machine is RUNNING, connecting...") exec_winssh(params) } diff --git a/config.go b/config.go index 412ed6d..61d7aa6 100644 --- a/config.go +++ b/config.go @@ -1,13 +1,19 @@ package main import ( + "encoding/json" "fmt" + "io/ioutil" "os" "path/filepath" ) type ConfigJson struct { - ClientSecretsFile string `json:"client_secrets_file"` + ClientSecretsFile string `json:"oauth_json_file"` + SSHFlags string `json:"ssh_flags"` + Debug bool `json:"debug"` + Proxy string `json:"proxy"` + UrlFetch string `json:"urlfetch"` } // Global Flags @@ -68,29 +74,41 @@ func init_config() error { config.AbsPath = path - // in, err := os.Open( config.AbsPath + "/config.json") + // config.json + in, err := os.Open(config.AbsPath + "/config.json") - // if err != nil { - // fmt.Println(err) - // return err - // } + if err != nil { + // fmt.Println(err) + } else { + + defer in.Close() + + data, _ := ioutil.ReadAll(in) - // defer in.Close() + var configJson ConfigJson - // data, err := ioutil.ReadAll(in) + err = json.Unmarshal(data, &configJson) - // var configJson ConfigJson + if err != nil { + fmt.Println("Error: Cannot unmarshal JSON: ", err) + return err + } - // err = json.Unmarshal(data, &configJson) + config.ClientSecretsFile = configJson.ClientSecretsFile - // if err != nil { - // fmt.Println("Error: Cannot unmarshal JSON: ", err) - // return err - // } + if configJson.SSHFlags != "" && configJson.SSHFlags != "default" { + config.sshFlags = []string{configJson.SSHFlags} + } - // config.ClientSecretsFile = configJson.ClientSecretsFile + config.Debug = configJson.Debug - // fmt.Println("Client Secrets File:", config.ClientSecretsFile) + if configJson.Proxy != "" { + config.Proxy = configJson.Proxy + } + + config.UrlFetch = configJson.UrlFetch + + } process_cmdline() diff --git a/config.json b/config.json index 6fdd01e..2239aa2 100644 --- a/config.json +++ b/config.json @@ -1,3 +1,7 @@ { - "client_secrets_file": "" -} + "debug": false, + "ssh_flags":"", + "proxy": "", + "urlfetch": "", + "oauth_json_file": "default" +} \ No newline at end of file diff --git a/winssh.go b/winssh.go index 8a77815..786d341 100644 --- a/winssh.go +++ b/winssh.go @@ -89,12 +89,12 @@ func exec_winssh(params CloudShellEnv) { // "curl -sSL https://raw.githubusercontent.com/ixiumu/google-cloud-shell-cli-go/patch-1/scripts-remote/heartbeats | sh & bash" err = client.Shell() - if err != nil && err.Error() != "exit status 255" { + if err != nil && config.Debug == true && err.Error() != "exit status 255" { fmt.Println("Failed to request shell - ", err) // return } - if config.Proxy != "" { + if config.Proxy == "v2ray" || config.Proxy == "shadowsocks" { proxy.Process.Kill() } From 3d86e3790b415af807771e53ffcbc0fb8cff3fbc Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 02:43:52 +0800 Subject: [PATCH 23/36] support winscp /rawsettings --- cloudshell.go | 4 ++-- cmdline.go | 3 ++- config.go | 9 +++++++++ config.json | 3 ++- winscp.go | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 063de99..5c2eecb 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -306,8 +306,8 @@ func call_cloud_shell(accessToken string) { host := params.SshHost port := fmt.Sprint(params.SshPort) - for x := 0; x < 60; x++ { - time.Sleep(500 * time.Millisecond) + for x := 0; x < 120; x++ { + time.Sleep(1000 * time.Millisecond) timeout := time.Second conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) diff --git a/cmdline.go b/cmdline.go index 00df862..637f92e 100644 --- a/cmdline.go +++ b/cmdline.go @@ -123,7 +123,8 @@ func process_cmdline() { } // WINSCP args if strings.HasPrefix(arg, "/rawsettings") { - config.sshFlags = append(config.sshFlags, os.Args[x:]...) + // config.sshFlags = append(config.sshFlags, os.Args[x:]...) + config.winscpFlags = os.Args[x:] break } // Proxy diff --git a/config.go b/config.go index 61d7aa6..1fc35c4 100644 --- a/config.go +++ b/config.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" ) type ConfigJson struct { @@ -14,6 +15,7 @@ type ConfigJson struct { Debug bool `json:"debug"` Proxy string `json:"proxy"` UrlFetch string `json:"urlfetch"` + WinscpFlags string `json:"winscp_flags"` } // Global Flags @@ -50,6 +52,9 @@ type Config struct { // Command line ssh options sshFlags []string + // Command line winscp options + winscpFlags []string + // ABS Path AbsPath string @@ -108,6 +113,10 @@ func init_config() error { config.UrlFetch = configJson.UrlFetch + if configJson.WinscpFlags != "" { + config.winscpFlags = append([]string{"/rawsettings"}, strings.Fields(configJson.WinscpFlags)...) + } + } process_cmdline() diff --git a/config.json b/config.json index 2239aa2..e834910 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,7 @@ { "debug": false, - "ssh_flags":"", + "ssh_flags": "", + "winscp_flags": "", "proxy": "", "urlfetch": "", "oauth_json_file": "default" diff --git a/winscp.go b/winscp.go index 085b05c..5bc4bd4 100644 --- a/winscp.go +++ b/winscp.go @@ -18,7 +18,7 @@ func exec_winscp(params CloudShellEnv) { sshPort := fmt.Sprint(params.SshPort) sshUrl := "sftp://" + sshUsername + "@" + sshHost + ":" + sshPort - args := append([]string{"/ini=nul", "/privatekey=" + key, "/hostkey=*", sshUrl}, config.sshFlags...) + args := append([]string{"/ini=nul", "/privatekey=" + key, "/hostkey=*", sshUrl}, config.winscpFlags...) if config.Debug == true { fmt.Println(key) From 3a301f448a81ddf56ad7e81981b8bee1f58e821d Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 03:41:31 +0800 Subject: [PATCH 24/36] mv config path --- auth.go | 8 ++++---- cmdline.go | 4 ++-- config.go | 28 ++++++++++++++++++++++++++-- main.go | 4 ++-- winssh.go | 10 +++++----- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/auth.go b/auth.go index 859a82d..b920fd8 100644 --- a/auth.go +++ b/auth.go @@ -56,7 +56,7 @@ type OAuthTokens struct { func readCredentials(filename string) ([]byte, error) { - in, err := os.Open(config.AbsPath + "/" + filename) + in, err := os.Open(filename) if err != nil { return []byte(""), err } @@ -137,8 +137,8 @@ func saveUserCredentials(filename string, creds UserCredentials) error { return err } - // err = ioutil.WriteFile(filename + ".test", j, 0644) - err = ioutil.WriteFile(config.AbsPath+"/"+filename, j, 0644) + // err = ioutil.WriteFile(filename+".test", j, 0644) + err = ioutil.WriteFile(filename, j, 0644) if err != nil { fmt.Println(err) @@ -448,7 +448,7 @@ func get_tokens() (string, string, error) { // fmt.Println("Login:", config.Flags.Login) if config.Flags.Auth == false { - if fileExists(config.AbsPath + "/" + SavedUserCredentials) { + if fileExists(SavedUserCredentials) { accessToken, idToken, valid := doRefresh(SavedUserCredentials) if valid == true { diff --git a/cmdline.go b/cmdline.go index 637f92e..5329ae5 100644 --- a/cmdline.go +++ b/cmdline.go @@ -133,11 +133,11 @@ func process_cmdline() { x++ continue } - if arg == "-v2ray" || arg == "--v2" { + if arg == "-v2" || arg == "--v2ray" { config.Proxy = "v2ray" continue } - if arg == "-shadowsocks" || arg == "--ss" { + if arg == "-ss" || arg == "--shadowsocks" { config.Proxy = "shadowsocks" continue } diff --git a/config.go b/config.go index 1fc35c4..c664a06 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "os/user" "path/filepath" "strings" ) @@ -55,8 +56,9 @@ type Config struct { // Command line winscp options winscpFlags []string - // ABS Path - AbsPath string + // Path + AbsPath string + PluginsPath string // proxy Proxy string @@ -78,6 +80,7 @@ func init_config() error { path = filepath.Dir(path) config.AbsPath = path + config.PluginsPath = path + "/plugins" // config.json in, err := os.Open(config.AbsPath + "/config.json") @@ -123,3 +126,24 @@ func init_config() error { return nil } + +func user_credentials_path() string { + + // UserCredentials + user, err := user.Current() + if err == nil { + configPath := user.HomeDir + "/.config/cloudshell/" + + _, err := os.Stat(configPath) + if err != nil { + err = os.Mkdir(configPath, os.ModePerm) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + } + + return configPath + "user_credentials.json" + } + return "user_credentials.json" +} diff --git a/main.go b/main.go index 774ceca..05187bb 100644 --- a/main.go +++ b/main.go @@ -12,8 +12,8 @@ import ( // This is the file where User Credentails are saved after authorization // This credentials are loaded on program start and refreshed if previously saved -var SavedUserCredentials = "user_credentials.json" -var SavedAdcCredentials = "adc_credentials.json" +// ~/.config/cloudshell/user_credentials.json +var SavedUserCredentials = user_credentials_path() // If you change the scopes, delete the saved user_credentials.json var SCOPE = "https://www.googleapis.com/auth/cloud-platform openid https://www.googleapis.com/auth/userinfo.email" diff --git a/winssh.go b/winssh.go index 786d341..69fbe75 100644 --- a/winssh.go +++ b/winssh.go @@ -59,7 +59,7 @@ func exec_winssh(params CloudShellEnv) { config.sshFlags = append(config.sshFlags, "-o", "ProxyCommand=connect.exe -S "+config.Proxy+" %h %p") } - sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") + sshBinaryPath, err := exec.LookPath(config.PluginsPath + "/ssh") if err != nil { sshBinaryPath, err = exec.LookPath("ssh") if err != nil { @@ -102,7 +102,7 @@ func exec_winssh(params CloudShellEnv) { func exec_vscode_ssh() { - sshBinaryPath, err := exec.LookPath(config.AbsPath + "/ssh") + sshBinaryPath, err := exec.LookPath(config.PluginsPath + "/ssh") if err != nil { sshBinaryPath, err = exec.LookPath("ssh") if err != nil { @@ -131,7 +131,7 @@ func exec_vscode_ssh() { } func V2ray(sshHost string, sshPort string) { - ssBinaryPath, err := exec.LookPath(config.AbsPath + "/v2ray/v2ray.exe") + ssBinaryPath, err := exec.LookPath(config.PluginsPath + "/v2ray/v2ray.exe") if err != nil { fmt.Println("Failed to create proxy client - ", err) return @@ -167,7 +167,7 @@ func ShadowSocks(sshHost string, sshPort string) { ssArgs = append(ssArgs, "-s", sshHost) ssArgs = append(ssArgs, "-p", sshPort) - ssBinaryPath, err := exec.LookPath(config.AbsPath + "/shadowsocks-libev/ss-local.exe") + ssBinaryPath, err := exec.LookPath(config.PluginsPath + "/shadowsocks-libev/ss-local.exe") // fmt.Println(ssBinaryPath) @@ -176,7 +176,7 @@ func ShadowSocks(sshHost string, sshPort string) { return } - ssPluginBinaryPath, err := exec.LookPath(config.AbsPath + "/shadowsocks-libev/v2ray-plugin.exe") + ssPluginBinaryPath, err := exec.LookPath(config.PluginsPath + "/shadowsocks-libev/v2ray-plugin.exe") if err != nil { fmt.Println("Failed to find proxy plugin - ", err) return From 0c3eefab1c399d99559789b8ce237c699186419b Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 03:55:30 +0800 Subject: [PATCH 25/36] fix --- config.go | 11 +++++++---- main.go | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/config.go b/config.go index c664a06..d360e9a 100644 --- a/config.go +++ b/config.go @@ -83,7 +83,10 @@ func init_config() error { config.PluginsPath = path + "/plugins" // config.json - in, err := os.Open(config.AbsPath + "/config.json") + in, err := os.Open(user_config_path("/config.json")) + if err != nil { + in, err = os.Open(config.AbsPath + "/config.json") + } if err != nil { // fmt.Println(err) @@ -127,7 +130,7 @@ func init_config() error { return nil } -func user_credentials_path() string { +func user_config_path(filename string) string { // UserCredentials user, err := user.Current() @@ -143,7 +146,7 @@ func user_credentials_path() string { } } - return configPath + "user_credentials.json" + return configPath + filename } - return "user_credentials.json" + return filename } diff --git a/main.go b/main.go index 05187bb..5e35895 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ import ( // This is the file where User Credentails are saved after authorization // This credentials are loaded on program start and refreshed if previously saved // ~/.config/cloudshell/user_credentials.json -var SavedUserCredentials = user_credentials_path() +var SavedUserCredentials = user_config_path("user_credentials.json") // If you change the scopes, delete the saved user_credentials.json var SCOPE = "https://www.googleapis.com/auth/cloud-platform openid https://www.googleapis.com/auth/userinfo.email" From 2612d59f1ba4eeba833ea96c6905edb03e91492b Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 16:12:59 +0800 Subject: [PATCH 26/36] clear user_credentials.json --- .gitignore | 1 + auth.go | 301 +++++++++++++++++++++++++---------------------------- main.go | 5 +- 3 files changed, 143 insertions(+), 164 deletions(-) diff --git a/.gitignore b/.gitignore index f1c181e..d7c7d63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.code-workspace # Binaries for programs and plugins *.exe *.exe~ diff --git a/auth.go b/auth.go index b920fd8..a6ba9fb 100644 --- a/auth.go +++ b/auth.go @@ -31,16 +31,16 @@ type ClientSecrets struct { } type UserCredentials struct { - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` + // ClientID string `json:"client_id"` + // ClientSecret string `json:"client_secret"` RefreshToken string `json:"refresh_token"` - Scope string `json:"scope"` - Type string `json:"type"` + // Scope string `json:"scope"` + // Type string `json:"type"` // The following two fields are option and exist after authentication AccessToken string `json:"access_token"` - IDToken string `json:"id_token"` - Email string `json:"email"` - ExpiresAt int64 `json:"expires_at"` + // IDToken string `json:"id_token"` + // Email string `json:"email"` + ExpiresAt int64 `json:"expires"` } type OAuthTokens struct { @@ -158,32 +158,7 @@ func fileExists(filename string) bool { return !info.IsDir() } -func debug_PrintUserCredentials(creds UserCredentials) { - fmt.Println("************************************************************") - fmt.Println("ClientID:", creds.ClientID) - fmt.Println("ClientSecret:", creds.ClientSecret) - fmt.Println("RefreshToken:", creds.RefreshToken) - fmt.Println("Scope:", creds.Scope) - fmt.Println("Type:", creds.Type) - fmt.Println("AccessToken:", creds.AccessToken) - fmt.Println("IDToken:", creds.IDToken) - fmt.Println("ExpiresAt:", creds.ExpiresAt) - - fmt.Println("Expires At:", time.Unix(creds.ExpiresAt, 0)) - - var t time.Time = time.Unix(creds.ExpiresAt, 0) - var expires_in int64 = 0 - - if time.Now().Before(t) { - expires_in = int64(creds.ExpiresAt) - int64(time.Now().UTC().Unix()) - fmt.Println("Expires In:", expires_in) - } else { - fmt.Println("Expires In: Expired") - } - fmt.Println("************************************************************") -} - -func doRefresh(filename string) (string, string, bool) { +func doRefresh(filename string) (string, bool) { endpoint := "https://www.googleapis.com/oauth2/v4/token" if config.UrlFetch != "" { @@ -194,11 +169,9 @@ func doRefresh(filename string) (string, string, bool) { if err != nil { fmt.Println(err) - return "", "", false + return "", false } - // debug_PrintUserCredentials(creds) - // We want an access token that is good for a while. // Brand new tokens are valid for 3600 seconds // For testing require 15 minutes or 900 seconds @@ -213,15 +186,30 @@ func doRefresh(filename string) (string, string, bool) { fmt.Println("Saved credentials (Access Token) have not expired") } - return creds.AccessToken, creds.IDToken, true + return creds.AccessToken, true } if config.Debug == true { fmt.Println("Must Refresh Token") } - content := "client_id=" + creds.ClientID + "&" - content += "client_secret=" + creds.ClientSecret + "&" + //************************************************************ + // Load the Google Client Secrets + //************************************************************ + + secrets, err := loadClientSecrets(config.ClientSecretsFile) + + if err != nil { + fmt.Println(err) + return "", false + } + + //************************************************************ + // Build the authenticate URL + //************************************************************ + + content := "client_id=" + secrets.Installed.ClientID + "&" + content += "client_secret=" + secrets.Installed.ClientSecret + "&" content += "grant_type=refresh_token&" content += "refresh_token=" + creds.RefreshToken @@ -233,14 +221,14 @@ func doRefresh(filename string) (string, string, bool) { if err != nil { fmt.Println("Error: ", err) - return "", "", false + return "", false } body, err := res.Body() if err != nil { fmt.Println("Error: ", err) - return "", "", false + return "", false } var tokens OAuthTokens @@ -249,42 +237,33 @@ func doRefresh(filename string) (string, string, bool) { if err != nil { fmt.Println("Error: Cannot unmarshal JSON: ", err) - return "", "", false + return "", false } - var expires_at int64 = int64(time.Now().UTC().Unix()) + int64(tokens.ExpiresIn) - - /* - fmt.Println("AccessToken:", tokens.AccessToken) - fmt.Println("ExpiresIn:", tokens.ExpiresIn) - fmt.Println("ExpiresAt:", expires_at) - fmt.Println("Scope:", tokens.Scope) - fmt.Println("TokenType:", tokens.TokenType) - fmt.Println("IDToken:", tokens.IDToken) - */ + var expires int64 = int64(time.Now().UTC().Unix()) + int64(tokens.ExpiresIn) creds.AccessToken = tokens.AccessToken - creds.IDToken = tokens.IDToken - creds.ExpiresAt = expires_at + // creds.IDToken = tokens.IDToken + creds.ExpiresAt = expires - email, err := get_email_address(tokens.AccessToken) + // email, err := get_email_address(tokens.AccessToken) - if err == nil { - if config.Debug == true { - fmt.Println("Email:", email) - } + // if err == nil { + // if config.Debug == true { + // fmt.Println("Email:", email) + // } - creds.Email = email - } + // creds.Email = email + // } err = saveUserCredentials(filename, creds) if err != nil { fmt.Println("Error: Cannot save user credentials: ", err) - return "", "", false + return "", false } - return creds.AccessToken, creds.IDToken, true + return creds.AccessToken, true } func debug_displayAccessToken(accessToken string) { @@ -343,98 +322,98 @@ func debug_displayUserInfo(accessToken string) { fmt.Println(string(body)) } -func debug_displayIDToken(accessToken, idToken string) { - endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" +// func debug_displayIDToken(accessToken, idToken string) { +// endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" - endpoint += "?id_token=" + idToken +// endpoint += "?id_token=" + idToken - if config.UrlFetch != "" { - endpoint = config.UrlFetch + endpoint - } +// if config.UrlFetch != "" { +// endpoint = config.UrlFetch + endpoint +// } - req := HttpRequest.NewRequest() +// req := HttpRequest.NewRequest() - req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) +// req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) - res, err := req.Get(endpoint) +// res, err := req.Get(endpoint) - if err != nil { - fmt.Println("Error: ", err) - return - } +// if err != nil { +// fmt.Println("Error: ", err) +// return +// } - body, err := res.Body() +// body, err := res.Body() - if err != nil { - fmt.Println("Error: ", err) - return - } +// if err != nil { +// fmt.Println("Error: ", err) +// return +// } - fmt.Println(string(body)) -} +// fmt.Println(string(body)) +// } -func get_email_address(accessToken string) (string, error) { - type Access_Token struct { - Azp string `json:"azp"` - Aud string `json:"aud"` - Sub string `json:"sub"` - Scope string `json:"scope"` - Exp string `json:"exp"` - Expires_in string `json:"expires_in"` - Email string `json:"email"` - Email_verified string `json:"email_verified"` - Access_type string `json:"access_type"` - } +// func get_email_address(accessToken string) (string, error) { +// type Access_Token struct { +// Azp string `json:"azp"` +// Aud string `json:"aud"` +// Sub string `json:"sub"` +// Scope string `json:"scope"` +// Exp string `json:"exp"` +// Expires_in string `json:"expires_in"` +// Email string `json:"email"` +// Email_verified string `json:"email_verified"` +// Access_type string `json:"access_type"` +// } - //************************************************************ - // - //************************************************************ +// //************************************************************ +// // +// //************************************************************ - endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" +// endpoint := "https://www.googleapis.com/oauth2/v3/tokeninfo" - if config.UrlFetch != "" { - endpoint = config.UrlFetch + endpoint - } +// if config.UrlFetch != "" { +// endpoint = config.UrlFetch + endpoint +// } - req := HttpRequest.NewRequest() +// req := HttpRequest.NewRequest() - req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) +// req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) - //************************************************************ - // - //************************************************************ +// //************************************************************ +// // +// //************************************************************ - res, err := req.Get(endpoint) +// res, err := req.Get(endpoint) - if err != nil { - fmt.Println("Error: ", err) - return "", err - } +// if err != nil { +// fmt.Println("Error: ", err) +// return "", err +// } - body, err := res.Body() +// body, err := res.Body() - if err != nil { - fmt.Println("Error: ", err) - return "", err - } +// if err != nil { +// fmt.Println("Error: ", err) +// return "", err +// } - //************************************************************ - // - //************************************************************ +// //************************************************************ +// // +// //************************************************************ - var tokens Access_Token +// var tokens Access_Token - err = json.Unmarshal(body, &tokens) +// err = json.Unmarshal(body, &tokens) - if err != nil { - fmt.Println("Error: Cannot unmarshal JSON: ", err) - return "", err - } +// if err != nil { +// fmt.Println("Error: Cannot unmarshal JSON: ", err) +// return "", err +// } - return tokens.Email, nil -} +// return tokens.Email, nil +// } -func get_tokens() (string, string, error) { +func get_tokens() (string, error) { //************************************************************ // Note: Application Default Credentials only work on Compute // Engine when interfacing with Cloud Shell. @@ -449,17 +428,17 @@ func get_tokens() (string, string, error) { if config.Flags.Auth == false { if fileExists(SavedUserCredentials) { - accessToken, idToken, valid := doRefresh(SavedUserCredentials) + accessToken, valid := doRefresh(SavedUserCredentials) if valid == true { - // fmt.Println("Access Token: ", accessToken) + fmt.Println("Access Token: ", accessToken) // fmt.Println("ID Token: ", idToken) // debug_displayAccessToken(accessToken) // debug_displayUserInfo(accessToken) // debug_displayIDToken(accessToken, idToken) - return accessToken, idToken, nil + return accessToken, nil } } } @@ -472,7 +451,7 @@ func get_tokens() (string, string, error) { if err != nil { fmt.Println(err) - return "", "", err + return "", err } //************************************************************ @@ -493,30 +472,28 @@ func get_tokens() (string, string, error) { return manualAuthentication(secrets, url) } -func get_sa_tokens() (string, string, error) { - - scope := "https://www.googleapis.com/auth/cloud-platform" +func get_sa_tokens() (string, error) { ctx := context.Background() - creds, err := google.FindDefaultCredentials(ctx, scope) + creds, err := google.FindDefaultCredentials(ctx, SCOPE) if err != nil { fmt.Println(err) - return "", "", err + return "", err } token, err := creds.TokenSource.Token() if err != nil { fmt.Println(err) - return "", "", err + return "", err } - return token.AccessToken, "", nil + return token.AccessToken, nil } -func manualAuthentication(secrets ClientSecrets, url string) (string, string, error) { +func manualAuthentication(secrets ClientSecrets, url string) (string, error) { fmt.Print("Go to the following link in your browser:\n\n" + url + "\n\nEnter verification code: ") @@ -529,7 +506,7 @@ func manualAuthentication(secrets ClientSecrets, url string) (string, string, er return processAuthCode(secrets, auth_code) } -func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, error) { +func processAuthCode(secrets ClientSecrets, auth_code string) (string, error) { //************************************************************ content := "client_id=" + secrets.Installed.ClientID content += "&client_secret=" + secrets.Installed.ClientSecret @@ -548,14 +525,14 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e if err != nil { fmt.Println("Error: ", err) - return "", "", err + return "", err } body, err := res.Body() if err != nil { fmt.Println("Error: ", err) - return "", "", err + return "", err } if config.Debug == true { @@ -572,7 +549,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e if err != nil { fmt.Println("Error: Cannot unmarshal JSON: ", err) - return "", "", err + return "", err } if config.Debug == true { @@ -583,39 +560,39 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e fmt.Println("Error: Cannot authenticate") fmt.Println(tokens.Error) fmt.Println(tokens.ErrorDescription) - return "", "", errors.New(tokens.ErrorDescription) + return "", errors.New(tokens.ErrorDescription) } //************************************************************ // //************************************************************ - var expires_at int64 = int64(time.Now().UTC().Unix()) + int64(tokens.ExpiresIn) + var expires int64 = int64(time.Now().UTC().Unix()) + int64(tokens.ExpiresIn) var creds UserCredentials - creds.ClientID = secrets.Installed.ClientID - creds.ClientSecret = secrets.Installed.ClientSecret + // creds.ClientID = secrets.Installed.ClientID + // creds.ClientSecret = secrets.Installed.ClientSecret creds.RefreshToken = tokens.RefreshToken - creds.Scope = tokens.Scope - creds.Type = tokens.TokenType + // creds.Scope = tokens.Scope + // creds.Type = tokens.TokenType creds.AccessToken = tokens.AccessToken - creds.IDToken = tokens.IDToken - creds.ExpiresAt = expires_at + // creds.IDToken = tokens.IDToken + creds.ExpiresAt = expires //************************************************************ // //************************************************************ - email, err := get_email_address(creds.AccessToken) + // email, err := get_email_address(creds.AccessToken) - if err == nil { - fmt.Println("Email:", email) + // if err == nil { + // fmt.Println("Email:", email) - creds.Email = email - } + // creds.Email = email + // } //************************************************************ // @@ -625,7 +602,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e if err != nil { fmt.Println("Error: Cannot save user credentials: ", err) - return "", "", err + return "", err } //************************************************************ @@ -634,9 +611,9 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, string, e if config.Debug == true { debug_displayAccessToken(creds.AccessToken) - debug_displayUserInfo(creds.AccessToken) - debug_displayIDToken(creds.AccessToken, creds.IDToken) + // debug_displayUserInfo(creds.AccessToken) + // debug_displayIDToken(creds.AccessToken, creds.IDToken) } - return creds.AccessToken, creds.IDToken, nil + return creds.AccessToken, nil } diff --git a/main.go b/main.go index 5e35895..dc3c9f5 100644 --- a/main.go +++ b/main.go @@ -16,7 +16,8 @@ import ( var SavedUserCredentials = user_config_path("user_credentials.json") // If you change the scopes, delete the saved user_credentials.json -var SCOPE = "https://www.googleapis.com/auth/cloud-platform openid https://www.googleapis.com/auth/userinfo.email" +// var SCOPE = "https://www.googleapis.com/auth/cloud-platform openid https://www.googleapis.com/auth/userinfo.email" +var SCOPE = "https://www.googleapis.com/auth/cloud-platform" func main() { //************************************************************ @@ -63,7 +64,7 @@ func main() { var accessToken = "" // accessToken, idToken, err := get_tokens() - accessToken, _, err = get_tokens() + accessToken, err = get_tokens() if err != nil { os.Exit(1) From a20b7ad77aa4b3f8bb22bb3955a93a52f3d1931c Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 16:44:07 +0800 Subject: [PATCH 27/36] fix config.json sshflags --- auth.go | 2 +- config.go | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/auth.go b/auth.go index a6ba9fb..445d539 100644 --- a/auth.go +++ b/auth.go @@ -431,7 +431,7 @@ func get_tokens() (string, error) { accessToken, valid := doRefresh(SavedUserCredentials) if valid == true { - fmt.Println("Access Token: ", accessToken) + // fmt.Println("Access Token: ", accessToken) // fmt.Println("ID Token: ", idToken) // debug_displayAccessToken(accessToken) diff --git a/config.go b/config.go index d360e9a..f8d3eca 100644 --- a/config.go +++ b/config.go @@ -11,12 +11,12 @@ import ( ) type ConfigJson struct { - ClientSecretsFile string `json:"oauth_json_file"` - SSHFlags string `json:"ssh_flags"` - Debug bool `json:"debug"` - Proxy string `json:"proxy"` - UrlFetch string `json:"urlfetch"` - WinscpFlags string `json:"winscp_flags"` + ClientSecretsFile string `json:"oauth_json_file"` + SSHFlags []string `json:"ssh_flags"` + Debug bool `json:"debug"` + Proxy string `json:"proxy"` + UrlFetch string `json:"urlfetch"` + WinscpFlags string `json:"winscp_flags"` } // Global Flags @@ -105,10 +105,12 @@ func init_config() error { return err } - config.ClientSecretsFile = configJson.ClientSecretsFile + if configJson.ClientSecretsFile != "" && configJson.ClientSecretsFile != "default" { + config.ClientSecretsFile = configJson.ClientSecretsFile + } - if configJson.SSHFlags != "" && configJson.SSHFlags != "default" { - config.sshFlags = []string{configJson.SSHFlags} + if len(configJson.SSHFlags) > 0 { + config.sshFlags = configJson.SSHFlags } config.Debug = configJson.Debug From 8aa4e9c7d36be8a40462676b676c24912f5c2833 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 16:45:10 +0800 Subject: [PATCH 28/36] config.json --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index e834910..17d747a 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { "debug": false, - "ssh_flags": "", + "ssh_flags": ["-o","LocalForward 127.0.0.1:8080 127.0.0.1:8080","-o","LocalForward 127.0.0.1:8443 127.0.0.1:8443"], "winscp_flags": "", "proxy": "", "urlfetch": "", From bcb42b3f460118ade018258d8504e9b1e5698554 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 17:23:03 +0800 Subject: [PATCH 29/36] fix --- auth.go | 11 ++++++----- cmdline.go | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/auth.go b/auth.go index 445d539..fdc7622 100644 --- a/auth.go +++ b/auth.go @@ -73,17 +73,18 @@ func loadClientSecrets(filename string) (ClientSecrets, error) { var data []byte var err error - if filename == "" { + if filename != "" { data, err = readCredentials(filename) + + if err != nil { + fmt.Println("Error: Cannot read credentials JSON file \""+filename+"\"", err) + os.Exit(1) + } } else { // data, err = base64.StdEncoding.DecodeString("eyJpbnN0YWxsZWQiOnsiY2xpZW50X2lkIjoiNjU4OTM5NTQ0ODM3LXNtaHR1MG42N3A3MGdqM2o0Y2JtZGw2NmNma3RhcWx2LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwicHJvamVjdF9pZCI6InhjbG91ZHNoZWxsIiwiYXV0aF91cmkiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvYXV0aCIsInRva2VuX3VyaSI6Imh0dHBzOi8vb2F1dGgyLmdvb2dsZWFwaXMuY29tL3Rva2VuIiwiYXV0aF9wcm92aWRlcl94NTA5X2NlcnRfdXJsIjoiaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YxL2NlcnRzIiwiY2xpZW50X3NlY3JldCI6ImJEUEN4eTl3LTlac0ZoQ2hpX243Yk5ERyIsInJlZGlyZWN0X3VyaXMiOlsidXJuOmlldGY6d2c6b2F1dGg6Mi4wOm9vYiIsImh0dHA6Ly9sb2NhbGhvc3QiXX19") } - if err != nil { - return secrets, err - } - // fmt.Println(string(data)) err = json.Unmarshal(data, &secrets) diff --git a/cmdline.go b/cmdline.go index 5329ae5..2b64856 100644 --- a/cmdline.go +++ b/cmdline.go @@ -276,10 +276,10 @@ func process_cmdline() { func cmd_help() { fmt.Println("Usage: cloudshell [command]") - fmt.Println(" cloudshell - display Cloud Shell information") fmt.Println(" cloudshell info - display Cloud Shell information") if isWindows() == true { fmt.Println(" cloudshell putty - connect to Cloud Shell with Putty") + fmt.Println(" cloudshell winscp - connect to Cloud Shell with WinSCP") } fmt.Println(" cloudshell ssh - connect to Cloud Shell with SSH") fmt.Println(" cloudshell exec \"command\" - Execute remote command on Cloud Shell") From b102023b1e204f9db89bda3307fa54b062fe2ebc Mon Sep 17 00:00:00 2001 From: ixiumu Date: Mon, 16 Sep 2019 22:21:32 +0800 Subject: [PATCH 30/36] :construction: Work in progress --- auth.go | 10 ++++++++-- cloudshell.go | 5 +++++ config.go | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/auth.go b/auth.go index fdc7622..cb51e20 100644 --- a/auth.go +++ b/auth.go @@ -95,7 +95,7 @@ func loadClientSecrets(filename string) (ClientSecrets, error) { return secrets, err } - config.ProjectId = secrets.Installed.ProjectID + // config.ProjectId = secrets.Installed.ProjectID // fmt.Println("ClientID:", secrets.Installed.ClientID) @@ -292,6 +292,7 @@ func debug_displayAccessToken(accessToken string) { return } + fmt.Println("Token Info: ") fmt.Println(string(body)) } @@ -470,7 +471,12 @@ func get_tokens() (string, error) { url += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" - return manualAuthentication(secrets, url) + token, err := manualAuthentication(secrets, url) + + // Wait for token to take effect + time.Sleep(1000 * time.Millisecond) + + return token, err } func get_sa_tokens() (string, error) { diff --git a/cloudshell.go b/cloudshell.go index 5c2eecb..f2434e6 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -66,6 +66,11 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell "Authorization": "Bearer " + accessToken, "X-Goog-User-Project": config.ProjectId}) + if config.Debug == true { + fmt.Println("Access Token:", accessToken) + fmt.Println("ProjectId:", config.ProjectId) + } + //************************************************************ // //************************************************************ diff --git a/config.go b/config.go index f8d3eca..ef8c1f8 100644 --- a/config.go +++ b/config.go @@ -12,6 +12,7 @@ import ( type ConfigJson struct { ClientSecretsFile string `json:"oauth_json_file"` + UserCredentials string `json:"user_credentials_json_file"` SSHFlags []string `json:"ssh_flags"` Debug bool `json:"debug"` Proxy string `json:"proxy"` @@ -109,6 +110,13 @@ func init_config() error { config.ClientSecretsFile = configJson.ClientSecretsFile } + if configJson.UserCredentials != "" { + SavedUserCredentials = configJson.UserCredentials + if strings.HasPrefix(SavedUserCredentials, "./") { + SavedUserCredentials = config.AbsPath + "/" + SavedUserCredentials + } + } + if len(configJson.SSHFlags) > 0 { config.sshFlags = configJson.SSHFlags } From bb83f70aca595374744aaf95ef805f35c9b27161 Mon Sep 17 00:00:00 2001 From: ixiumu Date: Tue, 17 Sep 2019 03:46:28 +0800 Subject: [PATCH 31/36] add --- cloudshell.go | 149 +++++++++++++++++++++++++++++++++++++++----------- cmdline.go | 6 ++ 2 files changed, 123 insertions(+), 32 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index f2434e6..8a808d1 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -4,7 +4,10 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "net" + "os" + "strings" "time" "github.com/kirinlabs/HttpRequest" @@ -178,75 +181,157 @@ func cloudshell_start(accessToken string) error { return nil } -func env_get_ssh_pkey() (string, error) { - //************************************************************* - // Return the Google Cloud SSH Key for the current Windows User - //************************************************************* +func cloud_shell_create_publickeys(accessToken string) error { + + fmt.Println("Pushing your public key to Cloud Shell...") + + endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default/publicKeys" + endpoint += "?alt=json" + + if config.UrlFetch != "" { + endpoint = config.UrlFetch + endpoint + } + + req := HttpRequest.NewRequest() + + req.SetHeaders(map[string]string{ + "Authorization": "Bearer " + accessToken, + "X-Goog-User-Project": config.ProjectId}) + + if config.Debug == true { + fmt.Println("Access Token:", accessToken) + fmt.Println("ProjectId:", config.ProjectId) + } - path, err := get_home_directory() + //************************************************************ + // + //************************************************************ + path, err := env_get_ssh_pub_key() if err != nil { - fmt.Println(err) - return "", err + fmt.Println("Error: ", err) + return err + } + + bytes, err := ioutil.ReadFile(path) + if err != nil { + fmt.Println("Error: ", err) + } + + keyFields := strings.Fields(string(bytes)) + + pubkey := keyFields[1] + + res, err := req.JSON().Post(endpoint, "{\"key\":{\"format\": \"SSH_RSA\",\"key\": \""+pubkey+"\"}}") + if err != nil { + fmt.Println("Error: ", err) + return err + } + + body, err := res.Body() + if err != nil { + fmt.Println("Error: ", err) + return err } - if isWindows() == true { - path += "\\.ssh\\google_compute_engine" - } else { - path += "/.ssh/google_compute_engine" + type Params struct { + Name string `json:"name"` + Format string `json:"format"` + Key string `json:"key"` + Error struct { + Code int32 `json:"code"` + Message string `json:"message"` + } `json:"error"` + } + + var params Params + + err = json.Unmarshal(body, ¶ms) + + if err != nil { + fmt.Println("Error: Cannot unmarshal JSON: ", err) + return err } if config.Debug == true { - fmt.Println("Path:", path) + fmt.Println("Body:", params) } - if fileExists(path) == false { - err = errors.New("Google SSH Key does not exist") - fmt.Println("Error:", err) - fmt.Println("File:", path) - return "", err + if params.Error.Code != 0 { + fmt.Println("Error:", params.Error.Message) } - return path, nil + return nil } -func env_get_ssh_ppk() (string, error) { +func env_get_ssh_key(filename string, ext string) (string, error) { //************************************************************* - // Return the Google Cloud SSH Key for the current Windows User + // Return the Google Cloud SSH Key for the current User //************************************************************* - path, err := get_home_directory() + // var path string + homepath, err := get_home_directory() if err != nil { fmt.Println(err) return "", err } - if isWindows() == true { - path += "\\.ssh\\google_compute_engine.ppk" - } else { - path += "/.ssh/google_compute_engine.ppk" + // if isWindows() == true { + // path = homepath + "\\.ssh\\" + filename + ext + // } else { + // path = homepath + "/.ssh/" + filename + ext + // } + + path := homepath + "/.ssh/" + filename + ext + if fileExists(path) == false { + path = homepath + "/.ssh/id_rsa_cloudshell" + ext + if fileExists(path) == false { + path = homepath + "/.ssh/id_rsa" + ext + if fileExists(path) == false { + err = errors.New("SSH Key does not exist") + fmt.Println("Error:", err) + fmt.Println("File:", homepath+"/.ssh/id_rsa"+ext) + fmt.Println("Please create and upload SSH key first") + fmt.Println("\n\n$ ssh-keygen -t rsa -C \"Cloud Shell\"") + fmt.Println("$ cloudshell push_pubkey\n\n ") + return "", err + } + } } if config.Debug == true { fmt.Println("Path:", path) } - if fileExists(path) == false { - err = errors.New("Google SSH Key does not exist") - fmt.Println("Error:", err) - fmt.Println("File:", path) - return "", err - } - return path, nil } +func env_get_ssh_pkey() (string, error) { + return env_get_ssh_key("google_compute_engine", "") +} + +func env_get_ssh_ppk() (string, error) { + return env_get_ssh_key("google_compute_engine", ".ppk") +} + +func env_get_ssh_pub_key() (string, error) { + return env_get_ssh_key("google_compute_engine", ".pub") +} + func call_cloud_shell(accessToken string) { //************************************************************ // //************************************************************ + if config.Command == CREATE_PUBKEY { + err := cloud_shell_create_publickeys(accessToken) + if err != nil { + fmt.Println("Error:", err) + } + os.Exit(0) + } + flag_info := false if config.Command == CMD_EXEC { diff --git a/cmdline.go b/cmdline.go index 2b64856..689cc41 100644 --- a/cmdline.go +++ b/cmdline.go @@ -19,6 +19,7 @@ const ( CMD_DOWNLOAD CMD_PUTTY CMD_WINSCP + CREATE_PUBKEY ) func process_cmdline() { @@ -260,6 +261,10 @@ func process_cmdline() { os.Exit(1) } + case "push_pubkey": + config.Command = CREATE_PUBKEY + return + default: if config.Command != 0 { return @@ -285,6 +290,7 @@ func cmd_help() { fmt.Println(" cloudshell exec \"command\" - Execute remote command on Cloud Shell") fmt.Println(" cloudshell upload src_file dst_file - Upload local file to Cloud Shell") fmt.Println(" cloudshell download src_file dst_file - Download from Cloud Shell to local file") + fmt.Println(" cloudshell push_pubkey - Push your public key to Cloud Shell") fmt.Println("") fmt.Println("--debug - Turn on debug output") fmt.Println("--adc - Use Application Default Credentials - Compute Engine only") From 49c850e6927137c738f6684c9c460917655e8b6a Mon Sep 17 00:00:00 2001 From: ixiumu Date: Tue, 17 Sep 2019 03:54:40 +0800 Subject: [PATCH 32/36] :construction: Work in progress --- auth.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth.go b/auth.go index cb51e20..8afb6e8 100644 --- a/auth.go +++ b/auth.go @@ -474,7 +474,7 @@ func get_tokens() (string, error) { token, err := manualAuthentication(secrets, url) // Wait for token to take effect - time.Sleep(1000 * time.Millisecond) + // time.Sleep(1000 * time.Millisecond) return token, err } From 563a294345d9395cb99a86b7bd20df32319d125f Mon Sep 17 00:00:00 2001 From: Calvin Chia <3610680+ixiumu@users.noreply.github.com> Date: Sat, 22 Jun 2024 19:58:21 +0000 Subject: [PATCH 33/36] fix --- cloudshell.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cloudshell.go b/cloudshell.go index 8a808d1..bc3405d 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -49,14 +49,14 @@ type CloudShellEnv struct { //****************************************************************************************** // Method: users.environments.get -// https://cloud.google.com/shell/docs/reference/rest/v1alpha1/users.environments/get +// https://cloud.google.com/shell/docs/reference/rest/v1/users.environments/get //****************************************************************************************** func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShellEnv, error) { var params CloudShellEnv - endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default" + endpoint := "https://cloudshell.googleapis.com/v1/users/me/environments/default" endpoint += "?alt=json" if config.UrlFetch != "" { @@ -114,7 +114,7 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell //****************************************************************************************** // Method: users.environment.start -// https://cloud.google.com/shell/docs/reference/rest/v1alpha1/users.environments/start +// https://cloud.google.com/shell/docs/reference/rest/v1/users.environments/start //****************************************************************************************** func cloudshell_start(accessToken string) error { @@ -126,7 +126,7 @@ func cloudshell_start(accessToken string) error { fmt.Println("Request users.environment.start") } - endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default" + endpoint := "https://cloudshell.googleapis.com/v1/users/me/environments/default" endpoint += ":start" endpoint += "?alt=json" @@ -185,7 +185,7 @@ func cloud_shell_create_publickeys(accessToken string) error { fmt.Println("Pushing your public key to Cloud Shell...") - endpoint := "https://cloudshell.googleapis.com/v1alpha1/users/me/environments/default/publicKeys" + endpoint := "https://cloudshell.googleapis.com/v1/users/me/environments/default/publicKeys" endpoint += "?alt=json" if config.UrlFetch != "" { From 8e053371a8b650b28a0dcd25783598041ddb1f40 Mon Sep 17 00:00:00 2001 From: Calvin Chia <3610680+ixiumu@users.noreply.github.com> Date: Sat, 22 Jun 2024 20:53:09 +0000 Subject: [PATCH 34/36] fix --- auth.go | 10 +++++----- cloudshell.go | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/auth.go b/auth.go index 8afb6e8..d8cf8b7 100644 --- a/auth.go +++ b/auth.go @@ -214,7 +214,7 @@ func doRefresh(filename string) (string, bool) { content += "grant_type=refresh_token&" content += "refresh_token=" + creds.RefreshToken - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{"Content-Type": "application/x-www-form-urlencoded"}) @@ -274,7 +274,7 @@ func debug_displayAccessToken(accessToken string) { endpoint = config.UrlFetch + endpoint } - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) @@ -303,7 +303,7 @@ func debug_displayUserInfo(accessToken string) { endpoint = config.UrlFetch + endpoint } - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{"Authorization": "Bearer " + accessToken}) @@ -524,9 +524,9 @@ func processAuthCode(secrets ClientSecrets, auth_code string) (string, error) { endpoint := "https://www.googleapis.com/oauth2/v4/token" - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) - req.SetHeaders(map[string]string{"Content-Type": "application/x-www-form-urlencoded"}) + //req.SetHeaders(map[string]string{"Content-Type": "application/x-www-form-urlencoded"}) res, err := req.Post(endpoint, content) diff --git a/cloudshell.go b/cloudshell.go index bc3405d..a6de0d2 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -63,7 +63,7 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell endpoint = config.UrlFetch + endpoint } - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{ "Authorization": "Bearer " + accessToken, @@ -134,7 +134,7 @@ func cloudshell_start(accessToken string) error { endpoint = config.UrlFetch + endpoint } - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{ "Authorization": "Bearer " + accessToken, @@ -192,7 +192,7 @@ func cloud_shell_create_publickeys(accessToken string) error { endpoint = config.UrlFetch + endpoint } - req := HttpRequest.NewRequest() + req := HttpRequest.NewRequest().SetTimeout(5 * time.Second) req.SetHeaders(map[string]string{ "Authorization": "Bearer " + accessToken, From 7cbd8d2ea900c8dca27a3d94d34a017e10ec386b Mon Sep 17 00:00:00 2001 From: Calvin Chia <3610680+ixiumu@users.noreply.github.com> Date: Sun, 23 Jun 2024 07:44:22 +0000 Subject: [PATCH 35/36] mg --- go.mod | 17 ++++++++++++++++ go.sum | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..605673d --- /dev/null +++ b/go.mod @@ -0,0 +1,17 @@ +module example.com/m + +go 1.22.3 + +require ( + github.com/kirinlabs/HttpRequest v1.1.2 + github.com/pkg/sftp v1.13.6 + golang.org/x/crypto v0.24.0 + golang.org/x/oauth2 v0.21.0 +) + +require ( + cloud.google.com/go/compute/metadata v0.3.0 // indirect + github.com/kr/fs v0.1.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..96e4410 --- /dev/null +++ b/go.sum @@ -0,0 +1,62 @@ +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/kirinlabs/HttpRequest v1.1.2 h1:W7EkRCTnxwq9PcIMXvITX8rCHfoPNzqR13RObSEe6bI= +github.com/kirinlabs/HttpRequest v1.1.2/go.mod h1:XV38fA4rXZox83tlEV9KIQ7Cdsut319x6NGzVLuRlB8= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= +github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 7021b6369fb8c2de06b782f11fcf2bf604b734e8 Mon Sep 17 00:00:00 2001 From: Calvin Chia <3610680+ixiumu@users.noreply.github.com> Date: Sun, 23 Jun 2024 07:45:10 +0000 Subject: [PATCH 36/36] backup --- auth.go | 33 +++++++------- bitvise.go | 12 ++--- cloudshell.go | 41 ++++++++++------- cmdline.go | 22 +++++----- config.go | 11 ++--- env.go | 4 +- main.go | 2 +- putty.go | 2 +- sftp.go | 11 ++--- sftp_benchmark.go | 10 ++--- sftp_conn.go | 3 +- ssh.go | 9 ++-- winscp.go | 2 +- winssh.go | 110 +++++++++++++++++++++++----------------------- 14 files changed, 140 insertions(+), 132 deletions(-) diff --git a/auth.go b/auth.go index 2124969..c2ffe4e 100644 --- a/auth.go +++ b/auth.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io/ioutil" + "log" "os" "os/exec" "strings" @@ -128,7 +129,7 @@ func loadUserCredentials(filename string) (UserCredentials, error) { } func saveUserCredentials(filename string, creds UserCredentials) error { - if config.Debug == true { + if config.Debug { fmt.Println("Save Credentials to:", filename) } @@ -209,14 +210,14 @@ func doRefresh(filename string) (string, string, bool) { // fmt.Println(time.Now()) if time.Now().Before(t) { - if config.Debug == true { + if config.Debug { fmt.Println("Saved credentials (Access Token) have not expired") } - return creds.AccessToken, true + return creds.AccessToken, creds.IDToken, true } - if config.Debug == true { + if config.Debug { fmt.Println("Must Refresh Token") } @@ -285,7 +286,7 @@ func doRefresh(filename string) (string, string, bool) { // email, err := get_email_address(tokens.AccessToken) // if err == nil { - // if config.Debug == true { + // if config.Debug { // fmt.Println("Email:", email) // } @@ -456,7 +457,7 @@ func get_tokens() (string, string, error) { // Engine when interfacing with Cloud Shell. //************************************************************ - if config.Flags.Adc == true { + if config.Flags.Adc { return get_sa_tokens() } @@ -467,7 +468,7 @@ func get_tokens() (string, string, error) { if fileExists(SavedUserCredentials) { accessToken, idToken, valid := doRefresh(SavedUserCredentials) - if valid == true { + if valid { // fmt.Println("Access Token: ", accessToken) // fmt.Println("ID Token: ", idToken) @@ -488,7 +489,7 @@ func get_tokens() (string, string, error) { if err != nil { fmt.Println(err) - return "", err + return "", "", err } //************************************************************ @@ -520,10 +521,10 @@ func get_tokens() (string, string, error) { url += "&login_hint=" + config.Flags.Login } - if isWindows() == true { + if isWindows() { url += "&redirect_uri=http://localhost:9000" } else { - if flag_desktop == true { + if flag_desktop { url += "&redirect_uri=http://localhost:9000" } else { url += "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" @@ -547,13 +548,13 @@ func get_tokens() (string, string, error) { } } - if config.Debug == true { + if config.Debug { fmt.Println("Python Path:", python_path) } //************************************************************ - if isWindows() == true { + if isWindows() { chrome, err := FindChromeBrowser() var cmd *exec.Cmd @@ -603,7 +604,7 @@ func get_tokens() (string, string, error) { log.Fatal("Error: Missing OAuth2 Code") } - if config.Debug == true { + if config.Debug { fmt.Println("OAuth2 Code:", string(out)) } @@ -702,7 +703,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string, flag_oob bool) (st return "", "", err } - if config.Debug == true { + if config.Debug { fmt.Println("BODY:", string(body)) } @@ -719,7 +720,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string, flag_oob bool) (st return "", "", err } - if config.Debug == true { + if config.Debug { fmt.Println("JSON:", tokens) } @@ -776,7 +777,7 @@ func processAuthCode(secrets ClientSecrets, auth_code string, flag_oob bool) (st // //************************************************************ - if config.Debug == true { + if config.Debug { debug_displayAccessToken(creds.AccessToken) // debug_displayUserInfo(creds.AccessToken) // debug_displayIDToken(creds.AccessToken, creds.IDToken) diff --git a/bitvise.go b/bitvise.go index 6afc084..fcf51e2 100644 --- a/bitvise.go +++ b/bitvise.go @@ -10,7 +10,7 @@ import ( // Also supports loading a profile // BvSsh.exe -profile= -var path_bitvise = "C:\\Program Files (x86)\\Bitvise SSH Client\\BvSsh.exe" +var path_bitvise = "C:\\Program Files (x86)\\Bitvise SSH Client\\BvSsh.exe" func exec_bitvise(params CloudShellEnv) { key, err := env_get_ssh_ppk() @@ -27,13 +27,13 @@ func exec_bitvise(params CloudShellEnv) { args := []string{} - args = append(args, "-host=" + sshHost) - args = append(args, "-port=" + sshPort) - args = append(args, "-user=" + sshUsername) - args = append(args, "-keypairFile=" + key) + args = append(args, "-host="+sshHost) + args = append(args, "-port="+sshPort) + args = append(args, "-user="+sshUsername) + args = append(args, "-keypairFile="+key) args = append(args, "-loginOnStartup") - if config.Debug == true { + if config.Debug { fmt.Println(key) fmt.Println(sshUsername) fmt.Println(sshHost) diff --git a/cloudshell.go b/cloudshell.go index 0a27f97..58074ee 100644 --- a/cloudshell.go +++ b/cloudshell.go @@ -72,7 +72,7 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell req.SetHeaders(hdrs) - if config.Debug == true { + if config.Debug { fmt.Println("Access Token:", accessToken) fmt.Println("ProjectId:", config.ProjectId) } @@ -95,7 +95,7 @@ func cloud_shell_get_environment(accessToken string, flag_info bool) (CloudShell return params, err } - if flag_info == true { + if flag_info { fmt.Println("Cloud Shell Info:") fmt.Println(string(body)) } @@ -125,7 +125,7 @@ func cloudshell_start(accessToken string) error { // //************************************************************ - if config.Debug == true { + if config.Debug { fmt.Println("Request users.environment.start") } @@ -160,7 +160,7 @@ func cloudshell_start(accessToken string) error { return err } - if config.Debug == true { + if config.Debug { fmt.Println("") fmt.Println("************************************************************") fmt.Println("Cloud Shell Info:") @@ -204,7 +204,7 @@ func cloud_shell_create_publickeys(accessToken string) error { "Authorization": "Bearer " + accessToken, "X-Goog-User-Project": config.ProjectId}) - if config.Debug == true { + if config.Debug { fmt.Println("Access Token:", accessToken) fmt.Println("ProjectId:", config.ProjectId) } @@ -259,7 +259,7 @@ func cloud_shell_create_publickeys(accessToken string) error { return err } - if config.Debug == true { + if config.Debug { fmt.Println("Body:", params) } @@ -283,18 +283,18 @@ func env_get_ssh_key(filename string, ext string) (string, error) { return "", err } - // if isWindows() == true { + // if isWindows() { // path = homepath + "\\.ssh\\" + filename + ext // } else { // path = homepath + "/.ssh/" + filename + ext // } path := homepath + "/.ssh/" + filename + ext - if fileExists(path) == false { + if !fileExists(path) { path = homepath + "/.ssh/id_rsa_cloudshell" + ext - if fileExists(path) == false { + if !fileExists(path) { path = homepath + "/.ssh/id_rsa" + ext - if fileExists(path) == false { + if !fileExists(path) { err = errors.New("SSH Key does not exist") fmt.Println("Error:", err) fmt.Println("File:", homepath+"/.ssh/id_rsa"+ext) @@ -306,7 +306,7 @@ func env_get_ssh_key(filename string, ext string) (string, error) { } } - if config.Debug == true { + if config.Debug { fmt.Println("Path:", path) } @@ -349,14 +349,15 @@ func call_cloud_shell(accessToken string) { params, err := cloud_shell_get_environment(accessToken, flag_info) if err != nil { + fmt.Println("Error:", err) return } if config.Command == CMD_INFO { return } - if params.State == "DISABLED" { - if config.Debug == true { + if params.State == "DISABLED" || params.State == "SUSPENDED" { + if config.Debug { fmt.Println("CloudShell State:", params.State) } @@ -401,14 +402,14 @@ func call_cloud_shell(accessToken string) { timeout := time.Second conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) if err != nil { - if config.Debug == true { + if config.Debug { fmt.Println("Connecting error:", err) } continue } if conn != nil { defer conn.Close() - if config.Debug == true { + if config.Debug { fmt.Println("Opened", net.JoinHostPort(host, port)) } break @@ -422,12 +423,19 @@ func call_cloud_shell(accessToken string) { return } + if config.Debug { + fmt.Println("Command:", config.Command) + } + if config.Command == CMD_PUTTY { + fmt.Println("Your Cloud Shell machine is RUNNING, connecting...") exec_putty(params) } if config.Command == CMD_INLINE_SSH { - exec_inline_ssh(params) + // exec_inline_ssh(params) + fmt.Println("Your Cloud Shell machine is RUNNING, connecting...") + exec_winssh(params) } if config.Command == CMD_WINSSH { @@ -436,6 +444,7 @@ func call_cloud_shell(accessToken string) { } if config.Command == CMD_SSH { + fmt.Println("Your Cloud Shell machine is RUNNING, connecting...") exec_ssh(params) } diff --git a/cmdline.go b/cmdline.go index 4606d0d..a2288d9 100644 --- a/cmdline.go +++ b/cmdline.go @@ -109,7 +109,7 @@ func process_cmdline() { if os.Args[3] == "cloudshell" { config.Debug = true - if isWindows() == true { + if isWindows() { config.Command = CMD_WINSSH } else { config.Command = CMD_SSH @@ -132,7 +132,7 @@ func process_cmdline() { // WINSCP args if strings.HasPrefix(arg, "/rawsettings") { // config.sshFlags = append(config.sshFlags, os.Args[x:]...) - config.winscpFlags = os.Args[x:] + config.WinscpFlags = os.Args[x:] break } // Proxy @@ -186,14 +186,14 @@ func process_cmdline() { config.Command = CMD_INFO case "ssh": - if isWindows() == true { + if isWindows() { config.Command = CMD_INLINE_SSH } else { config.Command = CMD_SSH } case "bitvise": - if isWindows() == true { + if isWindows() { config.Command = CMD_BITVISE } else { fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") @@ -201,7 +201,7 @@ func process_cmdline() { } case "winssh": - if isWindows() == true { + if isWindows() { config.Command = CMD_WINSSH } else { fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") @@ -237,7 +237,7 @@ func process_cmdline() { config.DstFile = file } - if config.Debug == true { + if config.Debug { fmt.Println("SrcFile:", config.SrcFile) fmt.Println("DstFile:", config.DstFile) } @@ -270,13 +270,13 @@ func process_cmdline() { config.DstFile = file } - if config.Debug == true { + if config.Debug { fmt.Println("SrcFile:", config.SrcFile) fmt.Println("DstFile:", config.DstFile) } case "putty": - if isWindows() == true { + if isWindows() { config.Command = CMD_PUTTY } else { fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") @@ -284,7 +284,7 @@ func process_cmdline() { } case "winscp": - if isWindows() == true { + if isWindows() { config.Command = CMD_WINSCP } else { fmt.Println("Error: This command is only supported on Windows. For Linux use ssh") @@ -326,7 +326,7 @@ func process_cmdline() { os.Exit(1) } - if isWindows() == true { + if isWindows() { fmt.Println("Error: expected a command (info, putty, ssh, winssh, exec, upload, download)") } else { fmt.Println("Error: expected a command (info, ssh, exec, upload, download)") @@ -340,7 +340,7 @@ func cmd_help() { fmt.Println("Usage: cloudshell [command]") fmt.Println(" cloudshell - display cloudshell program help") fmt.Println(" cloudshell info - display Cloud Shell information") - if isWindows() == true { + if isWindows() { fmt.Println(" cloudshell putty - connect to Cloud Shell with Putty") fmt.Println(" cloudshell winscp - connect to Cloud Shell with WinSCP") } diff --git a/config.go b/config.go index 22aa608..bec3b8c 100644 --- a/config.go +++ b/config.go @@ -55,7 +55,7 @@ type Config struct { sshFlags []string // Command line winscp options - winscpFlags []string + WinscpFlags []string // Path AbsPath string @@ -133,19 +133,14 @@ func init_config() error { config.UrlFetch = configJson.UrlFetch if configJson.WinscpFlags != "" { - config.winscpFlags = append([]string{"/rawsettings"}, strings.Fields(configJson.WinscpFlags)...) + config.WinscpFlags = append([]string{"/rawsettings"}, strings.Fields(configJson.WinscpFlags)...) } + config.ClientSecretsFile = configJson.ClientSecretsFile } - config.ClientSecretsFile = configJson.ClientSecretsFile - // fmt.Println("Client Secrets File:", config.ClientSecretsFile) - if configJson.WinscpFlags != "" { - config.WinscpFlags = append([]string{"/rawsettings"}, strings.Fields(configJson.WinscpFlags)...) - } - process_cmdline() return nil diff --git a/env.go b/env.go index 2cf7981..146b3f8 100644 --- a/env.go +++ b/env.go @@ -9,14 +9,14 @@ import ( func isWindows() bool { if runtime.GOOS == "windows" { - return true; + return true } return false } func check_os() error { - if config.Debug == true { + if config.Debug { fmt.Println("Runtime Environment:") fmt.Printf(" OS: %s\n", runtime.GOOS) fmt.Printf(" ARCH: %s\n", runtime.GOARCH) diff --git a/main.go b/main.go index dc3c9f5..503c431 100644 --- a/main.go +++ b/main.go @@ -64,7 +64,7 @@ func main() { var accessToken = "" // accessToken, idToken, err := get_tokens() - accessToken, err = get_tokens() + accessToken, _, err = get_tokens() if err != nil { os.Exit(1) diff --git a/putty.go b/putty.go index 919fec1..3b164a0 100644 --- a/putty.go +++ b/putty.go @@ -18,7 +18,7 @@ func exec_putty(params CloudShellEnv) { sshPort := fmt.Sprint(params.SshPort) sshUrl := sshUsername + "@" + sshHost - if config.Debug == true { + if config.Debug { fmt.Println(key) fmt.Println(sshUsername) fmt.Println(sshHost) diff --git a/sftp.go b/sftp.go index 7e177f3..529c333 100644 --- a/sftp.go +++ b/sftp.go @@ -7,6 +7,7 @@ import ( "net" "os" "time" + "github.com/pkg/sftp" "golang.org/x/crypto/ssh" "golang.org/x/text/language" @@ -36,7 +37,7 @@ func sftp_download(params CloudShellEnv) { host := sshHost + ":" + sshPort - if config.Debug == true { + if config.Debug { fmt.Println("Dial") fmt.Println(host) } @@ -68,7 +69,7 @@ func sftp_download(params CloudShellEnv) { log.Fatal(err) } defer srcFile.Close() - + // create destination file fmt.Println("create destination file") dstFile, err := os.Create(config.DstFile) @@ -108,7 +109,7 @@ func sftp_upload(params CloudShellEnv) { host := sshHost + ":" + sshPort - if config.Debug == true { + if config.Debug { fmt.Println("Dial") fmt.Println(host) } @@ -146,7 +147,7 @@ func sftp_upload(params CloudShellEnv) { log.Fatal(err) } defer dstFile.Close() - + // copy source file to destination file bytes, err := io.Copy(dstFile, srcFile) if err != nil { @@ -165,7 +166,7 @@ func print_transfer_stats(total_time time.Duration, bytes int64, flag bool) { // Convert to milliseconds ms := int64(total_time) / 1000000 - if (bytes == 0) { + if bytes == 0 { fmt.Printf("%v bytes in %s - Speed 0 KBS\n", bytes, total_time) } else { kbs := bytes / ms diff --git a/sftp_benchmark.go b/sftp_benchmark.go index ec6ad6a..a5bad75 100644 --- a/sftp_benchmark.go +++ b/sftp_benchmark.go @@ -6,11 +6,11 @@ import ( "strconv" "syscall" "time" + "golang.org/x/text/language" "golang.org/x/text/message" ) - func sftp_benchmark_download(params CloudShellEnv) { //************************************************************ // @@ -25,7 +25,7 @@ func sftp_benchmark_download(params CloudShellEnv) { defer connection.Close() defer client.Close() - if config.Debug == true { + if config.Debug { fmt.Println("Connected") } @@ -80,7 +80,7 @@ func sftp_benchmark_download(params CloudShellEnv) { if err != nil { fmt.Println(err) - break; + break } if count != bufsize { @@ -121,7 +121,7 @@ func sftp_benchmark_upload(params CloudShellEnv) { defer connection.Close() defer client.Close() - if config.Debug == true { + if config.Debug { fmt.Println("Connected") } @@ -184,7 +184,7 @@ func sftp_benchmark_upload(params CloudShellEnv) { if err != nil { fmt.Println(err) - break; + break } if count != bufsize { diff --git a/sftp_conn.go b/sftp_conn.go index b21696b..aac55ff 100644 --- a/sftp_conn.go +++ b/sftp_conn.go @@ -3,6 +3,7 @@ package main import ( "fmt" "net" + "github.com/pkg/sftp" "golang.org/x/crypto/ssh" ) @@ -30,7 +31,7 @@ func sftp_open_connection(params CloudShellEnv) (*ssh.Client, *sftp.Client, erro host := sshHost + ":" + sshPort - if config.Debug == true { + if config.Debug { fmt.Println("Dial: " + host) } diff --git a/ssh.go b/ssh.go index f3b81d1..f59aadd 100644 --- a/ssh.go +++ b/ssh.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "time" + "golang.org/x/crypto/ssh" ) @@ -68,7 +69,7 @@ func exec_command(params CloudShellEnv) { defer connection.Close() - if config.Debug == true { + if config.Debug { fmt.Println("Connect") } @@ -88,7 +89,7 @@ func exec_command(params CloudShellEnv) { session.Stdout = &stdoutBuf session.Stderr = &stderrBuf - if config.Debug == true { + if config.Debug { fmt.Println("Run Command:", config.RemoteCommand) } @@ -110,7 +111,7 @@ func exec_ssh(params CloudShellEnv) { sshPort := fmt.Sprint(params.SshPort) sshUrl := sshUsername + "@" + sshHost - if config.Debug == true { + if config.Debug { fmt.Println(key) fmt.Println(sshUsername) fmt.Println(sshHost) @@ -118,7 +119,7 @@ func exec_ssh(params CloudShellEnv) { fmt.Println(sshUrl) } - for x:= 0; x < 3; x++ { + for x := 0; x < 3; x++ { if x > 0 { fmt.Println("Retrying ...") diff --git a/winscp.go b/winscp.go index 3bd368b..55c7f8c 100644 --- a/winscp.go +++ b/winscp.go @@ -22,7 +22,7 @@ func exec_winscp(params CloudShellEnv) { args := append([]string{"/ini=nul", "/privatekey=" + key, "/hostkey=*", sshUrl}, config.WinscpFlags...) - if config.Debug == true { + if config.Debug { fmt.Println(key) fmt.Println(sshUsername) fmt.Println(sshHost) diff --git a/winssh.go b/winssh.go index aa878d4..777f782 100644 --- a/winssh.go +++ b/winssh.go @@ -13,7 +13,7 @@ import ( "os" "runtime" // "golang.org/x/crypto/ssh" - "github.com/docker/machine/libmachine/ssh" + // "github.com/docker/machine/libmachine/ssh" ) // var path_winssh = "C:/Windows/System32/OpenSSH/ssh.exe" @@ -32,7 +32,7 @@ func exec_winssh(params CloudShellEnv) { sshPort := fmt.Sprint(params.SshPort) sshUrl := sshUsername + "@" + sshHost - if config.Debug == true { + if config.Debug { fmt.Println(key) fmt.Println(sshUsername) fmt.Println(sshHost) @@ -40,14 +40,14 @@ func exec_winssh(params CloudShellEnv) { fmt.Println(sshUrl) } - // if config.Debug == true { + // if config.Debug { // fmt.Println("cmd.exe /C start " + path_winssh + " " + sshUrl + " -p " + sshPort + " -i " + key) // } // cmd := exec.Command("cmd.exe", "/C", "start", path_winssh, sshUrl, "-p", sshPort, "-i", key) if config.Proxy == "v2ray" { - if config.Debug == true { + if config.Debug { fmt.Println("Proxy: V2ray") } @@ -55,7 +55,7 @@ func exec_winssh(params CloudShellEnv) { V2ray(sshHost, sshPort) CheckPort("127.0.0.1", "8022") } else if config.Proxy == "shadowsocks" { - if config.Debug == true { + if config.Debug { fmt.Println("Proxy: shadowsocks") } @@ -77,12 +77,12 @@ func exec_winssh(params CloudShellEnv) { } } - if config.Debug == true { + if config.Debug { fmt.Println("Use:", sshBinaryPath) } auth := Auth{Keys: []string{key}} - sshPortInt, err := strconv.Atoi(sshPort) + sshPortInt, _ := strconv.Atoi(sshPort) client, err := NewExternalClient(sshBinaryPath, sshUsername, sshHost, sshPortInt, &auth, config.sshFlags) if err != nil { @@ -95,7 +95,7 @@ func exec_winssh(params CloudShellEnv) { // "curl -sSL https://raw.githubusercontent.com/ixiumu/google-cloud-shell-cli-go/patch-1/scripts-remote/heartbeats | sh & bash" err = client.Shell() - if err != nil && config.Debug == true && err.Error() != "exit status 255" { + if err != nil && config.Debug && err.Error() != "exit status 255" { fmt.Println("Failed to request shell - ", err) // return } @@ -153,7 +153,7 @@ func V2ray(sshHost string, sshPort string) { return } - if config.Debug == true { + if config.Debug { fmt.Println("Proxy Config:", url) } @@ -200,7 +200,7 @@ func ShadowSocks(sshHost string, sshPort string) { return } - if config.Debug == true { + if config.Debug { fmt.Println("Proxy:", ssArgs) } @@ -221,14 +221,14 @@ func CheckUrlConfig(sshHost string, sshPort string) { defer resp.Body.Close() // if resp.StatusCode != http.StatusOK { - // if config.Debug == true { + // if config.Debug { // fmt.Println("Error: status code", resp.StatusCode) // } // continue // } if resp.StatusCode == 200 { - if config.Debug == true { + if config.Debug { fmt.Println("CheckPort: status code", resp.StatusCode) } break @@ -243,14 +243,14 @@ func CheckPort(host string, port string) { timeout := time.Second conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), timeout) if err != nil { - if config.Debug == true { + if config.Debug { fmt.Println("Connecting error:", err) } continue } if conn != nil { defer conn.Close() - if config.Debug == true { + if config.Debug { fmt.Println("Opened", net.JoinHostPort(host, port)) } break @@ -262,11 +262,11 @@ func (client *ExternalClient) HeartBeats() { time.Sleep(10 * time.Second) - if config.Debug == true { + if config.Debug { fmt.Print("Start Send HeartBeats") } - for true { + for { args := append(client.BaseArgs, "curl -I -H \"Devshell-Vm-Ip-Address:${DEVSHELL_IP_ADDRESS}\" -X POST -s -w %{http_code} -o /dev/null ${DEVSHELL_SERVER_URL}/devshell/vmheartbeat") cmd := getSSHCmd(client.BinaryPath, args...) @@ -276,7 +276,7 @@ func (client *ExternalClient) HeartBeats() { fmt.Print("HeartBeats error: ", err) } - if config.Debug == true { + if config.Debug { fmt.Print("HeartBeats: ", string(output)) } @@ -317,7 +317,7 @@ var ( "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", } - defaultClientType = External + // defaultClientType = External ) func NewExternalClient(sshBinaryPath, user, host string, port int, auth *Auth, flags []string) (*ExternalClient, error) { @@ -368,7 +368,7 @@ func NewExternalClient(sshBinaryPath, user, host string, port int, auth *Auth, f client.BaseArgs = args - if config.Debug == true { + if config.Debug { fmt.Println("sshArgs:", client.BaseArgs) } @@ -444,39 +444,39 @@ func closeConn(c io.Closer) { } } -func exec_inline_ssh(params CloudShellEnv) { - key, err := env_get_ssh_pkey() - - if err != nil { - fmt.Println("\nTip: Run the command: \"gcloud alpha cloud-shell ssh --dry-run\" to setup Cloud Shell SSH keys") - return - } - - sshUsername := params.SshUsername - sshHost := params.SshHost - sshPort := fmt.Sprint(params.SshPort) - sshUrl := sshUsername + "@" + sshHost - - if config.Debug == true { - fmt.Println(key) - fmt.Println(sshUsername) - fmt.Println(sshHost) - fmt.Println(sshPort) - fmt.Println(sshUrl) - } - - auth := ssh.Auth{Keys: []string{key}} - sshPortInt, err := strconv.Atoi(sshPort) - client, err := ssh.NewClient(sshUsername, sshHost, sshPortInt, &auth) - if err != nil { - fmt.Errorf("Failed to create new client - %s", err) - return - } - - err = client.Shell() - if err != nil && err.Error() != "exit status 255" { - fmt.Errorf("Failed to request shell - %s", err) - return - } - -} +// func exec_inline_ssh(params CloudShellEnv) { +// key, err := env_get_ssh_pkey() + +// if err != nil { +// fmt.Println("\nTip: Run the command: \"gcloud alpha cloud-shell ssh --dry-run\" to setup Cloud Shell SSH keys") +// return +// } + +// sshUsername := params.SshUsername +// sshHost := params.SshHost +// sshPort := fmt.Sprint(params.SshPort) +// sshUrl := sshUsername + "@" + sshHost + +// if config.Debug { +// fmt.Println(key) +// fmt.Println(sshUsername) +// fmt.Println(sshHost) +// fmt.Println(sshPort) +// fmt.Println(sshUrl) +// } + +// auth := ssh.Auth{Keys: []string{key}} +// sshPortInt, err := strconv.Atoi(sshPort) +// client, err := ssh.NewClient(sshUsername, sshHost, sshPortInt, &auth) +// if err != nil { +// fmt.Errorf("Failed to create new client - %s", err) +// return +// } + +// err = client.Shell() +// if err != nil && err.Error() != "exit status 255" { +// fmt.Errorf("Failed to request shell - %s", err) +// return +// } + +// }