From 611bdef44ab51a82af141005d998e6701e4f9a1f Mon Sep 17 00:00:00 2001 From: VHSgunzo Date: Mon, 16 Dec 2024 18:27:46 +0300 Subject: [PATCH] v0.3.1 --- README.md | 3 +++ ssrv.go | 65 ++++++++++++++++++++++++++++++++++++++++++++------- tls/README.md | 3 +++ tls/go.mod | 2 +- tls/go.sum | 2 ++ tls/ssrv.go | 65 ++++++++++++++++++++++++++++++++++++++++++++------- 6 files changed, 121 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d3798c3..39ae9bd 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,8 @@ Accepted options: Change the current working directory of the process/command. -env string Comma separated list of environment variables to pass to the server side process. (default "TERM") + -env-pids string + Comma separated list of PIDs for get environment variables for pass to the server side process. -no-pty Do not allocate a pseudo-terminal for the server side process -nosep-cpids @@ -64,6 +66,7 @@ Accepted options: Environment variables: SSRV_PTY=1 Same as -pty argument SSRV_NO_PTY=1 Same as -no-pty argument + SSRV_ENV_PIDS="123,456" Same as -env-pids argument SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument SSRV_UENV="MY_VAR,MY_VAR1" Same as -uenv argument SSRV_SOCK="tcp:1337" Same as -sock argument diff --git a/ssrv.go b/ssrv.go index 23bd5fc..224e56f 100644 --- a/ssrv.go +++ b/ssrv.go @@ -29,7 +29,7 @@ import ( "golang.org/x/term" ) -var VERSION string = "v0.2.9" +var VERSION string = "v0.3.1" const ENV_VARS = "TERM" const BINARY_NAME = "ssrv" @@ -51,6 +51,7 @@ const USAGE_FOOTER = ` Environment variables: SSRV_PTY=1 Same as -pty argument SSRV_NO_PTY=1 Same as -no-pty argument + SSRV_ENV_PIDS="123,456" Same as -env-pids argument SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument SSRV_UENV="MY_VAR,MY_VAR1" Same as -uenv argument SSRV_SOCK="tcp:1337" Same as -sock argument @@ -81,6 +82,10 @@ var socket_addr = flag.String( "sock", UNIX_SOCKET, "Socket address listen/connect (unix,tcp,tcp4,tcp6)", ) +var env_pids = flag.String( + "env-pids", "", + "Comma separated list of PIDs for get environment variables for pass to the server side process.", +) var env_vars = flag.String( "env", ENV_VARS, "Comma separated list of environment variables for pass to the server side process.", @@ -250,6 +255,10 @@ func ssrv_env_vars_parse() { !*nosep_cpids { flag.Set("nosep-cpids", "true") } + if ssrv_env_pids, ok := os.LookupEnv("SSRV_ENV_PIDS"); ok && + *env_pids == "" { + flag.Set("env-pids", ssrv_env_pids) + } if ssrv_env, ok := os.LookupEnv("SSRV_ENV"); ok && *env_vars == ENV_VARS { flag.Set("env", ssrv_env) @@ -308,6 +317,40 @@ func is_pid_exist(pid int) bool { return err == nil } +func setenv_environ_pids(pids string) { + if len(pids) != 0 { + for _, pid := range strings.Split(pids, ",") { + environ, err := read_environ(pid) + if err != nil { + log.Fatalln(err) + } + for key, value := range environ { + os.Setenv(key, value) + } + } + } +} + +func read_environ(pid string) (map[string]string, error) { + environ_path := fmt.Sprintf("/proc/%s/environ", pid) + data, err := os.ReadFile(environ_path) + if err != nil { + return nil, fmt.Errorf("failed to read environ file: %w", err) + } + environ := make(map[string]string) + pairs := strings.Split(string(data), "\000") + for _, pair := range pairs { + if pair == "" { + continue + } + parts := strings.SplitN(pair, "=", 2) + if len(parts) == 2 { + environ[parts[0]] = parts[1] + } + } + return environ, nil +} + func srv_handle(conn net.Conn, self_cpids_dir string) { var wg sync.WaitGroup disconnect := func(session *yamux.Session, remote string) { @@ -338,7 +381,7 @@ func srv_handle(conn net.Conn, self_cpids_dir string) { return } envs_str = envs_str[:len(envs_str)-1] - envs := strings.Split(envs_str, "%&&%") + envs := strings.Split(envs_str, "\000") is_alloc_pty := true var stdin_channel net.Conn @@ -401,7 +444,7 @@ func srv_handle(conn net.Conn, self_cpids_dir string) { if len(cmd_str) == 0 { cmd_str = get_shell() } - cmd := strings.Split(cmd_str, "%&&%") + cmd := strings.Split(cmd_str, "\000") exec_cmd := exec.Command(cmd[0], cmd[1:]...) exec_cmd_envs := os.Environ() @@ -649,6 +692,8 @@ func server(proto, socket string) { os.Exit(1) }() + setenv_environ_pids(*env_pids) + if *env_vars == "all" { for _, uenv := range strings.Split(*uenv_vars, ",") { os.Unsetenv(uenv) @@ -802,10 +847,12 @@ func client(proto, socket string, exec_args []string) int { is_alloc_pty = false } + setenv_environ_pids(*env_pids) + var envs string if *env_vars == "all" { for _, env := range os.Environ() { - envs += env + "%&&%" + envs += env + "\000" } } else if strings.HasPrefix(*env_vars, "all-:") { unset_env_vars := strings.Split(strings.Replace(*env_vars, "all-:", "", 1), ",") @@ -820,7 +867,7 @@ func client(proto, socket string, exec_args []string) int { } } if is_add_env { - envs += env + "%&&%" + envs += env + "\000" } } } else { @@ -829,15 +876,15 @@ func client(proto, socket string, exec_args []string) int { } for _, env := range strings.Split(*env_vars, ",") { if value, ok := os.LookupEnv(env); ok { - envs += env + "=" + value + "%&&%" + envs += env + "=" + value + "\000" } } } if len(*uenv_vars) != 0 { - envs += fmt.Sprintf("_SSRV_UENV=%s", *uenv_vars) + "%&&%" + envs += fmt.Sprintf("_SSRV_UENV=%s", *uenv_vars) + "\000" } if len(*cwd) != 0 { - envs += fmt.Sprintf("_SSRV_CWD=%s", *cwd) + "%&&%" + envs += fmt.Sprintf("_SSRV_CWD=%s", *cwd) + "\000" } if !is_alloc_pty { envs += "_NO_PTY_" @@ -874,7 +921,7 @@ func client(proto, socket string, exec_args []string) int { if err != nil { log.Fatalf("command channel open error: %v", err) } - command := strings.Join(exec_args, "%&&%") + "\r" + command := strings.Join(exec_args, "\000") + "\r" _, err = command_channel.Write([]byte(command)) if err != nil { log.Fatalf("failed to send command: %v", err) diff --git a/tls/README.md b/tls/README.md index 6fed60c..ced4455 100644 --- a/tls/README.md +++ b/tls/README.md @@ -48,6 +48,8 @@ Accepted options: Change the current working directory of the process/command. -env string Comma separated list of environment variables to pass to the server side process. (default "TERM") + -env-pids string + Comma separated list of PIDs for get environment variables for pass to the server side process. -no-pty Do not allocate a pseudo-terminal for the server side process -nosep-cpids @@ -74,6 +76,7 @@ Accepted options: Environment variables: SSRV_PTY=1 Same as -pty argument SSRV_NO_PTY=1 Same as -no-pty argument + SSRV_ENV_PIDS="123,456" Same as -env-pids argument SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument SSRV_UENV="MY_VAR,MY_VAR1" Same as -uenv argument SSRV_SOCK="tcp:1337" Same as -sock argument diff --git a/tls/go.mod b/tls/go.mod index 95ddac5..a28a229 100644 --- a/tls/go.mod +++ b/tls/go.mod @@ -20,6 +20,6 @@ require ( ) require ( - golang.org/x/crypto v0.30.0 + golang.org/x/crypto v0.31.0 golang.org/x/sys v0.28.0 ) diff --git a/tls/go.sum b/tls/go.sum index f8a690f..65035c0 100644 --- a/tls/go.sum +++ b/tls/go.sum @@ -31,6 +31,8 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/tls/ssrv.go b/tls/ssrv.go index dc1bf06..2c3c253 100644 --- a/tls/ssrv.go +++ b/tls/ssrv.go @@ -32,7 +32,7 @@ import ( "golang.org/x/term" ) -var VERSION string = "v0.2.9" +var VERSION string = "v0.3.1" const ENV_VARS = "TERM" const TLS_KEY = "key.pem" @@ -56,6 +56,7 @@ const USAGE_FOOTER = ` Environment variables: SSRV_PTY=1 Same as -pty argument SSRV_NO_PTY=1 Same as -no-pty argument + SSRV_ENV_PIDS="123,456" Same as -env-pids argument SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument SSRV_UENV="MY_VAR,MY_VAR1" Same as -uenv argument SSRV_SOCK="tcp:1337" Same as -sock argument @@ -88,6 +89,10 @@ var socket_addr = flag.String( "sock", UNIX_SOCKET, "Socket address listen/connect (unix,tcp,tcp4,tcp6)", ) +var env_pids = flag.String( + "env-pids", "", + "Comma separated list of PIDs for get environment variables for pass to the server side process.", +) var env_vars = flag.String( "env", ENV_VARS, "Comma separated list of environment variables for pass to the server side process.", @@ -265,6 +270,10 @@ func ssrv_env_vars_parse() { !*nosep_cpids { flag.Set("nosep-cpids", "true") } + if ssrv_env_pids, ok := os.LookupEnv("SSRV_ENV_PIDS"); ok && + *env_pids == "" { + flag.Set("env-pids", ssrv_env_pids) + } if ssrv_env, ok := os.LookupEnv("SSRV_ENV"); ok && *env_vars == ENV_VARS { flag.Set("env", ssrv_env) @@ -331,6 +340,40 @@ func is_pid_exist(pid int) bool { return err == nil } +func setenv_environ_pids(pids string) { + if len(pids) != 0 { + for _, pid := range strings.Split(pids, ",") { + environ, err := read_environ(pid) + if err != nil { + log.Fatalln(err) + } + for key, value := range environ { + os.Setenv(key, value) + } + } + } +} + +func read_environ(pid string) (map[string]string, error) { + environ_path := fmt.Sprintf("/proc/%s/environ", pid) + data, err := os.ReadFile(environ_path) + if err != nil { + return nil, fmt.Errorf("failed to read environ file: %w", err) + } + environ := make(map[string]string) + pairs := strings.Split(string(data), "\000") + for _, pair := range pairs { + if pair == "" { + continue + } + parts := strings.SplitN(pair, "=", 2) + if len(parts) == 2 { + environ[parts[0]] = parts[1] + } + } + return environ, nil +} + func get_cert_sha256(cert string) ([]byte, error) { cert_bytes, err := os.ReadFile(cert) if err != nil { @@ -414,7 +457,7 @@ func srv_handle(conn net.Conn, self_cpids_dir string) { return } envs_str = envs_str[:len(envs_str)-1] - envs := strings.Split(envs_str, "%&&%") + envs := strings.Split(envs_str, "\000") is_alloc_pty := true var stdin_channel net.Conn @@ -477,7 +520,7 @@ func srv_handle(conn net.Conn, self_cpids_dir string) { if len(cmd_str) == 0 { cmd_str = get_shell() } - cmd := strings.Split(cmd_str, "%&&%") + cmd := strings.Split(cmd_str, "\000") exec_cmd := exec.Command(cmd[0], cmd[1:]...) exec_cmd_envs := os.Environ() @@ -746,6 +789,8 @@ func server(proto, socket string) { os.Exit(1) }() + setenv_environ_pids(*env_pids) + if *env_vars == "all" { for _, uenv := range strings.Split(*uenv_vars, ",") { os.Unsetenv(uenv) @@ -928,10 +973,12 @@ func client(proto, socket string, exec_args []string) int { is_alloc_pty = false } + setenv_environ_pids(*env_pids) + var envs string if *env_vars == "all" { for _, env := range os.Environ() { - envs += env + "%&&%" + envs += env + "\000" } } else if strings.HasPrefix(*env_vars, "all-:") { unset_env_vars := strings.Split(strings.Replace(*env_vars, "all-:", "", 1), ",") @@ -946,7 +993,7 @@ func client(proto, socket string, exec_args []string) int { } } if is_add_env { - envs += env + "%&&%" + envs += env + "\000" } } } else { @@ -955,15 +1002,15 @@ func client(proto, socket string, exec_args []string) int { } for _, env := range strings.Split(*env_vars, ",") { if value, ok := os.LookupEnv(env); ok { - envs += env + "=" + value + "%&&%" + envs += env + "=" + value + "\000" } } } if len(*uenv_vars) != 0 { - envs += fmt.Sprintf("_SSRV_UENV=%s", *uenv_vars) + "%&&%" + envs += fmt.Sprintf("_SSRV_UENV=%s", *uenv_vars) + "\000" } if len(*cwd) != 0 { - envs += fmt.Sprintf("_SSRV_CWD=%s", *cwd) + "%&&%" + envs += fmt.Sprintf("_SSRV_CWD=%s", *cwd) + "\000" } if !is_alloc_pty { envs += "_NO_PTY_" @@ -1000,7 +1047,7 @@ func client(proto, socket string, exec_args []string) int { if err != nil { log.Fatalf("command channel open error: %v", err) } - command := strings.Join(exec_args, "%&&%") + "\r" + command := strings.Join(exec_args, "\000") + "\r" _, err = command_channel.Write([]byte(command)) if err != nil { log.Fatalf("failed to send command: %v", err)