Skip to content

Commit

Permalink
v0.1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
VHSgunzo committed Apr 15, 2024
1 parent bc23b40 commit fa68326
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 30 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.21.6
require (
github.com/creack/pty v1.1.21
github.com/hashicorp/yamux v0.1.1
golang.org/x/term v0.16.0
golang.org/x/term v0.19.0
)

require golang.org/x/sys v0.16.0 // indirect
require golang.org/x/sys v0.19.0 // indirect
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
8 changes: 8 additions & 0 deletions shellsrv.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ func srv_handle(conn net.Conn, self_cpids_dir string) {
log.Printf("[%s] [ DISCONNECTED ]", remote)
}

defer conn.Close()
remote := conn.RemoteAddr().String()

session, err := yamux.Server(conn, nil)
if err != nil {
log.Printf("[%s] session error: %v", remote, err)
Expand Down Expand Up @@ -489,13 +491,19 @@ func client(proto, socket string, exec_args []string) int {
if err != nil {
log.Fatalf("connection error: %v", err)
}
defer conn.Close()

session, err := yamux.Client(conn, nil)
if err != nil {
log.Fatalf("session error: %v", err)
}
defer session.Close()

_, err = session.Ping()
if err != nil {
log.Fatalf("ping error: %v", err)
}

stdin := int(os.Stdin.Fd())
is_stdin_term := false
if term.IsTerminal(stdin) {
Expand Down
8 changes: 4 additions & 4 deletions tls/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ cd shellsrv/tls

## **Usage**:
```
┌──[user@linux]─[~] - generate key.pem and cert.pem:
└──╼ $ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
┌──[user@linux]─[~] - Server:
└──╼ $ shellsrv -server [-tls-key key.pem] [-tls-cert cert.pem] [-socket tcp:1337]
┌──[user@linux]─[~] - Client:
└──╼ $ shellsrv -tls [options] [ COMMAND [ arguments... ] ]
└──╼ $ shellsrv [-tls-cert cert.pem] [options] [ COMMAND [ arguments... ] ]
If COMMAND is not passed, spawn a $SHELL on the server side.
Expand All @@ -50,10 +52,8 @@ Accepted options:
Run as server
-socket string
Socket address listen/connect (unix,tcp,tcp4,tcp6) (default "unix:@shellsrv")
-tls
Use TLS encryption for connect to server
-tls-cert string
TLS cert file for server (default "cert.pem")
TLS cert file for server and client (default "cert.pem")
-tls-key string
TLS key file for server (default "key.pem")
-version
Expand Down
7 changes: 5 additions & 2 deletions tls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ go 1.21.6
require (
github.com/creack/pty v1.1.21
github.com/hashicorp/yamux v0.1.1
golang.org/x/term v0.16.0
golang.org/x/term v0.19.0
)

require golang.org/x/sys v0.16.0 // indirect
require (
golang.org/x/crypto v0.22.0
golang.org/x/sys v0.19.0 // indirect
)
10 changes: 6 additions & 4 deletions tls/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
98 changes: 84 additions & 14 deletions tls/shellsrv.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"bufio"
"crypto/sha256"
"crypto/tls"
"encoding/gob"
"flag"
Expand All @@ -22,6 +23,7 @@ import (

"github.com/creack/pty"
"github.com/hashicorp/yamux"
"golang.org/x/crypto/bcrypt"
"golang.org/x/term"
)

Expand All @@ -31,7 +33,7 @@ const BINARY_NAME = "shellsrv"
const UNIX_SOCKET = "unix:@shellsrv"

const USAGE_PREAMBLE = `Server usage: %[1]s -server [-tls-key key.pem] [-tls-cert cert.pem] [-socket tcp:1337]
Client usage: %[1]s -tls [options] [ COMMAND [ arguments... ] ]
Client usage: %[1]s [-tls-cert cert.pem] [options] [ COMMAND [ arguments... ] ]
If COMMAND is not passed, spawn a $SHELL on the server side.
Expand All @@ -46,7 +48,6 @@ 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_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
Expand Down Expand Up @@ -92,13 +93,9 @@ var is_no_pty = flag.Bool(
"no-pty", false,
"Do not allocate a pseudo-terminal for the server side process",
)
var is_tls = flag.Bool(
"tls", false,
"Use TLS encryption for connect to server",
)
var tls_cert = flag.String(
"tls-cert", "cert.pem",
"TLS cert file for server",
"TLS cert file for server and client",
)
var tls_key = flag.String(
"tls-key", "key.pem",
Expand Down Expand Up @@ -242,9 +239,6 @@ func ssrv_env_vars_parse() {
if ssrv_env, ok := os.LookupEnv("SSRV_ENV"); ok {
flag.Set("env", ssrv_env)
}
if is_env_var_eq("SSRV_CLIENT_TLS", "1") {
flag.Set("tls", "true")
}
if tls_key, ok := os.LookupEnv("SSRV_TLS_KEY"); ok &&
is_file_exists(tls_key) {
flag.Set("tls-key", tls_key)
Expand All @@ -264,14 +258,69 @@ func ssrv_env_vars_parse() {
}
}

func get_cert_sha256(cert string) ([]byte, error) {
cert_bytes, err := os.ReadFile(cert)
if err != nil {
return []byte(""), err
}
cert_str := string(cert_bytes)
cert_str = strings.Replace(cert_str, "-----BEGIN CERTIFICATE-----", "-----CERT_SHA256-----", -1)
cert_str = strings.Replace(cert_str, "-----END CERTIFICATE-----", "-----CERT_SHA256-----", -1)
cert_sha256 := sha256.Sum256([]byte(cert_str))
return cert_sha256[:], nil
}

func get_cert_hash(cert string) (string, error) {
cert_sha256, err := get_cert_sha256(cert)
if err != nil {
return "", err
}
hash_bytes, err := bcrypt.GenerateFromPassword(cert_sha256, bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hash_bytes), nil
}

func verify_cert_hash(provided_cert_hash, cert string) (bool, error) {
cert_sha256, err := get_cert_sha256(cert)
if err != nil {
return false, err
}
err = bcrypt.CompareHashAndPassword([]byte(provided_cert_hash), cert_sha256)
if err != nil {
return false, nil
}
return true, nil
}

func srv_handle(conn net.Conn, self_cpids_dir string) {
var wg sync.WaitGroup
disconnect := func(session *yamux.Session, remote string) {
session.Close()
log.Printf("[%s] [ DISCONNECTED ]", remote)
}

defer conn.Close()
remote := conn.RemoteAddr().String()

if is_file_exists(*tls_cert) {
hash_buf := make([]byte, 60)
n, err := conn.Read(hash_buf)
if err != nil {
log.Printf("[%s] error reading cert hash: %v", remote, err)
return
}
provided_cert_hash := string(hash_buf[:n])
is_valid_cert_hash, err := verify_cert_hash(provided_cert_hash, *tls_cert)
if err != nil || !is_valid_cert_hash {
log.Printf("[%s] invalid cert!", remote)
conn.Write([]byte("error\r"))
return
}
conn.Write([]byte("\r"))
}

session, err := yamux.Server(conn, nil)
if err != nil {
log.Printf("[%s] session error: %v", remote, err)
Expand Down Expand Up @@ -457,7 +506,7 @@ func server(proto, socket string) {
}
tls_config := &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS12,
MinVersion: tls.VersionTLS13,
Certificates: []tls.Certificate{cert},
}
listener, err = tls.Listen(proto, socket, tls_config)
Expand Down Expand Up @@ -534,29 +583,50 @@ func client(proto, socket string, exec_args []string) int {
}

var conn net.Conn
if *is_tls {
if is_file_exists(*tls_cert) {
tls_config := &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS12,
MinVersion: tls.VersionTLS13,
}
conn, err = tls.Dial(proto, socket, tls_config)
if err != nil {
log.Fatalf("TLS connection error: %v", err)
}
cert_hash, err := get_cert_hash(*tls_cert)
if err != nil {
log.Fatalf("failed to get cert hash: %v", err)
}
_, err = conn.Write([]byte(cert_hash))
if err != nil {
log.Fatalf("failed to send cert hash: %v", err)
}
status_reader := bufio.NewReader(conn)
status, err := status_reader.ReadString('\r')
if err != nil {
log.Fatalf("error reading hash status: %v", err)
}
if strings.Contains(status, "error") {
log.Fatalf("invalid cert!")
}
} else {
conn, err = net.Dial(proto, socket)
if err != nil {
log.Fatalf("connection error: %v", err)
}

}
defer conn.Close()

session, err := yamux.Client(conn, nil)
if err != nil {
log.Fatalf("session error: %v", err)
}
defer session.Close()

_, err = session.Ping()
if err != nil {
log.Fatalf("ping error: %v", err)
}

stdin := int(os.Stdin.Fd())
is_stdin_term := false
if term.IsTerminal(stdin) {
Expand Down

0 comments on commit fa68326

Please sign in to comment.