Skip to content

Commit

Permalink
v0.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
VHSgunzo committed Mar 28, 2024
1 parent 5176964 commit dff2ac0
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 32 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ go install github.com/VHSgunzo/shellsrv@latest
If COMMAND is not passed, spawn a $SHELL on the server side.
Accepted options:
-cpids-dir string
A directory on the server side for storing a list of client PIDs. (default "/tmp/ssrv$EUID")
-env string
Comma separated list of environment variables to pass to the server side process. (default "TERM")
-no-pty
Do not allocate a pseudo-terminal for the server side process
-nosep-cpids
Don't create a separate dir for the server socket to store the list of client PIDs.
-pty
Force allocate a pseudo-terminal for the server side process
-server
Expand All @@ -50,6 +54,8 @@ Environment variables:
SSRV_NO_ALLOC_PTY=1 Same as -no-pty argument
SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument
SSRV_SOCKET="tcp:1337" Same as -socket argument
SSRV_CPIDS_DIR=/path/dir Same as -cpids-dir argument
SSRV_NOSEP_CPIDS=1 Same as -nosep-cpids argument
SHELL="/bin/bash" Assigns a default shell (on the server side)
--
Expand Down
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if [ ! -n "$ARCHS" ]
ARCHS="$(uname -m)"
fi
[ "$ARCHS" == 'all' ] && \
ARCHS=(source i386 x86_64 armv7 aarch64)
ARCHS=(source i386 x86_64 armv7 aarch64 arm64)

GIT_VERSION="$(git describe --long --tags 2>/dev/null|sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')"
[ -n "$GIT_VERSION" ] && \
Expand All @@ -42,6 +42,7 @@ for ARCH in "${ARCHS[@]}"
x86_64) GOARCH='amd64' ;;
armv7) GOARCH='arm' ;;
aarch64) GOARCH='arm64' ;;
arm64) export GOOS='darwin' ; GOARCH='arm64' ;;
*) GOARCH="$ARCH" ;;
esac
export GOARCH
Expand Down
107 changes: 91 additions & 16 deletions shellsrv.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"syscall"
"time"
"unsafe"

"github.com/creack/pty"
Expand Down Expand Up @@ -43,11 +44,13 @@ Environment variables:
SSRV_NO_ALLOC_PTY=1 Same as -no-pty argument
SSRV_ENV="MY_VAR,MY_VAR1" Same as -env argument
SSRV_SOCKET="tcp:1337" Same as -socket argument
SSRV_CPIDS_DIR=/path/dir Same as -cpids-dir argument
SSRV_NOSEP_CPIDS=1 Same as -nosep-cpids argument
SHELL="/bin/bash" Assigns a default shell (on the server side)
--
If none of the pty arguments are passed in the client, a pseudo-terminal is allocated by default, unless it is
If none of the pty arguments are passed in the client, a pseudo-terminal is allocated by default, unless it is
known that the command behaves incorrectly when attached to the pty or the client is not running in the terminal`

var is_alloc_pty = true
Expand Down Expand Up @@ -75,7 +78,6 @@ var is_version = flag.Bool(
"version", false,
"Show this program's version",
)

var is_pty = flag.Bool(
"pty", false,
"Force allocate a pseudo-terminal for the server side process",
Expand All @@ -84,6 +86,14 @@ var is_no_pty = flag.Bool(
"no-pty", false,
"Do not allocate a pseudo-terminal for the server side process",
)
var cpids_dir = flag.String(
"cpids-dir", fmt.Sprint("/tmp/ssrv", syscall.Geteuid()),
"A directory on the server side for storing a list of client PIDs.",
)
var nosep_cpids = flag.Bool(
"nosep-cpids", false,
"Don't create a separate dir for the server socket to store the list of client PIDs.",
)

type win_size struct {
ws_row uint16
Expand Down Expand Up @@ -118,6 +128,32 @@ func get_socket(addr []string) string {
return socket
}

func touch_file(path string) error {
_, err := os.Stat(path)
if os.IsNotExist(err) {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
} else {
currentTime := time.Now().Local()
err = os.Chtimes(path, currentTime, currentTime)
if err != nil {
return err
}
}
return nil
}

func is_dir_exists(dir string) bool {
info, err := os.Stat(dir)
if os.IsNotExist(err) {
return false
}
return info.IsDir()
}

func is_file_exists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
Expand Down Expand Up @@ -184,9 +220,15 @@ func ssrv_env_vars_parse() {
if ssrv_env, ok := os.LookupEnv("SSRV_ENV"); ok {
flag.Set("env", ssrv_env)
}
if ssrv_cpids_dir, ok := os.LookupEnv("SSRV_CPIDS_DIR"); ok {
flag.Set("cpids-dir", ssrv_cpids_dir)
}
if is_env_var_eq("SSRV_NOSEP_CPIDS", "1") {
flag.Set("nosep-cpids", "true")
}
}

func srv_handle(conn net.Conn) {
func srv_handle(conn net.Conn, self_cpids_dir string) {
disconnect := func(session *yamux.Session, remote string) {
session.Close()
log.Printf("[%s] [ DISCONNECTED ]", remote)
Expand Down Expand Up @@ -267,6 +309,19 @@ func srv_handle(conn net.Conn) {
cmd_pid := strconv.Itoa(exec_cmd.Process.Pid)
log.Printf("[%s] pid: %s", remote, cmd_pid)

cpid := fmt.Sprint(self_cpids_dir, "/", cmd_pid)
if is_dir_exists(self_cpids_dir) {
proc_pid := fmt.Sprint("/proc/", cmd_pid)
if is_dir_exists(proc_pid) {
if err := os.Symlink(proc_pid, cpid); err != nil {
log.Printf("[%s] symlink error: %v", remote, err)
return
}
} else {
touch_file(cpid)
}
}

if is_alloc_pty {
control_channel, err := session.Accept()
if err != nil {
Expand Down Expand Up @@ -327,20 +382,13 @@ func srv_handle(conn net.Conn) {
if err != nil {
log.Printf("[%s] error sending exit code: %v", remote, err)
}

os.Remove(cpid)
}

func server(proto, socket string) {
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sig
if proto == "unix" && is_file_exists(socket) {
os.Remove(socket)
}
os.Exit(1)
}()

listen, err := net.Listen(proto, socket)
listener, err := net.Listen(proto, socket)
if err != nil {
log.Fatal(err)
}
Expand All @@ -350,15 +398,42 @@ func server(proto, socket string) {
log.Fatalln("unix socket:", err)
}
}
log.Printf("listening on %s %s", listen.Addr().Network(), listen.Addr().String())
listener_addr := listener.Addr().String()
log.Printf("listening on %s %s", listener.Addr().Network(), listener_addr)

var self_cpids_dir string
if *nosep_cpids {
self_cpids_dir = *cpids_dir
} else {
listener_addr = strings.TrimLeft(listener_addr, "/")
listener_addr = strings.Replace(listener_addr, "/", "-", -1)
self_cpids_dir = fmt.Sprint(*cpids_dir, "/", listener_addr)
}

err = os.MkdirAll(self_cpids_dir, 0700)
if err != nil {
fmt.Println("creating directory error:", err)
}

sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sig
if proto == "unix" && is_file_exists(socket) {
os.Remove(socket)
}
os.RemoveAll(self_cpids_dir)
os.Remove(*cpids_dir)
os.Exit(1)
}()

for {
conn, err := listen.Accept()
conn, err := listener.Accept()
if err != nil {
log.Printf("[%s] accept error: %v", conn.RemoteAddr().String(), err)
continue
}
go srv_handle(conn)
go srv_handle(conn, self_cpids_dir)
}
}

Expand Down
6 changes: 6 additions & 0 deletions tls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ cd shellsrv/tls
If COMMAND is not passed, spawn a $SHELL on the server side.
Accepted options:
-cpids-dir string
A directory on the server side for storing a list of client PIDs. (default "/tmp/ssrv$EUID")
-env string
Comma separated list of environment variables to pass to the server side process. (default "TERM")
-no-pty
Do not allocate a pseudo-terminal for the server side process
-nosep-cpids
Don't create a separate dir for the server socket to store the list of client PIDs.
-pty
Force allocate a pseudo-terminal for the server side process
-server
Expand All @@ -62,6 +66,8 @@ Environment variables:
SSRV_CLIENT_TLS=1 Same as -tls argument
SSRV_TLS_KEY="/path/key.pem" Same as -tls-key argument
SSRV_TLS_CERT="/path/cert.pem" Same as -tls-cert argument
SSRV_CPIDS_DIR=/path/dir Same as -cpids-dir argument
SSRV_NOSEP_CPIDS=1 Same as -nosep-cpids argument
SHELL="/bin/bash" Assigns a default shell (on the server side)
--
Expand Down
3 changes: 2 additions & 1 deletion tls/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if [ ! -n "$ARCHS" ]
ARCHS="$(uname -m)"
fi
[ "$ARCHS" == 'all' ] && \
ARCHS=(source i386 x86_64 armv7 aarch64)
ARCHS=(source i386 x86_64 armv7 aarch64 arm64)

GIT_VERSION="$(git describe --long --tags 2>/dev/null|sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')"
[ -n "$GIT_VERSION" ] && \
Expand All @@ -42,6 +42,7 @@ for ARCH in "${ARCHS[@]}"
x86_64) GOARCH='amd64' ;;
armv7) GOARCH='arm' ;;
aarch64) GOARCH='arm64' ;;
arm64) export GOOS='darwin' ; GOARCH='arm64' ;;
*) GOARCH="$ARCH" ;;
esac
export GOARCH
Expand Down
Loading

0 comments on commit dff2ac0

Please sign in to comment.