From 5af8666e4da0b096c9642823b18ff13298295f5d Mon Sep 17 00:00:00 2001 From: Will Boyce Date: Mon, 10 Jul 2017 11:56:31 +0100 Subject: [PATCH 1/2] Add support for running shell with alternative credentials Fixes #23 Change-Type: minor --- resin/README.md | 4 ++++ resin/main.go | 18 ++++++++++++++++++ sshproxy.go | 8 +++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/resin/README.md b/resin/README.md index bfc4917..d2b1dc6 100644 --- a/resin/README.md +++ b/resin/README.md @@ -25,6 +25,8 @@ they can all be set via commandline, environment or config file. | Dir | `--dir` `-d` | `SSHPROXY_DIR` | | | Port | `--port` `-p` | `SSHPROXY_PORT` | `port` | | Shell | `--shell` `-s` | `SSHPROXY_SHELL` | `shell` | +| Shell Uid | `--shell-uid` `-u` | `SSHPROXY_SHELL_UID` | `shell-uid` | +| Shell Gid | `--shell-gid` `-g` | `SSHPROXY_SHELL_GID` | `shell-gid` | | Auth Failed Banner | `--auth-failed-banner` `-b` | `SSHPROXY_AUTH_FAILED_BANNER` | `auth-failed-banner` | | Max Auth Tries | `--max-auth-tries` `-m` | `SSHPROXY_MAX_AUTH_TRIES` | `max-auth-tries` | | Allow Env | `--allow-env` `-E` | `SSHPROXY_ALLOW_ENV` | `allow-env` | @@ -42,6 +44,8 @@ Usage of sshproxy: -p, --port int Port the ssh service will listen on (default 22) -S, --sentry-dsn string Sentry DSN for error reporting -s, --shell string Path to shell to execute post-authentication (default "shell.sh") + -g, --shell-gid int Group to run shell as (default: current gid) + -u, --shell-uid int User to run shell as (default: current uid) ``` ## Auth Failed Banner/Template diff --git a/resin/main.go b/resin/main.go index 5f89e63..0f158b3 100644 --- a/resin/main.go +++ b/resin/main.go @@ -26,6 +26,7 @@ import ( "log" "os" "path" + "syscall" "github.com/getsentry/raven-go" "github.com/resin-io/sshproxy" @@ -41,6 +42,8 @@ func init() { pflag.CommandLine.StringP("dir", "d", "/etc/sshproxy", "Work dir, holds ssh keys and sshproxy config") pflag.CommandLine.IntP("port", "p", 22, "Port the ssh service will listen on") pflag.CommandLine.StringP("shell", "s", "shell.sh", "Path to shell to execute post-authentication") + pflag.CommandLine.Int64P("shell-uid", "u", -1, "User to run shell as (default: current uid)") + pflag.CommandLine.Int64P("shell-gid", "g", -1, "Group to run shell as (default: current gid)") pflag.CommandLine.StringP("auth-failed-banner", "b", "", "Path to template displayed after failed authentication") pflag.CommandLine.IntP("max-auth-tries", "m", 0, "Maximum number of authentication attempts per connection (default 0; unlimited)") pflag.CommandLine.BoolP("allow-env", "E", false, "Pass environment from client to shell (default: false) (warning: security implications)") @@ -70,6 +73,12 @@ func init() { if err := viper.BindEnv("shell"); err != nil { return err } + if err := viper.BindEnv("shell-uid", "SSHPROXY_SHELL_UID"); err != nil { + return err + } + if err := viper.BindEnv("shell-gid", "SSHPROXY_SHELL_GID"); err != nil { + return err + } if err := viper.BindEnv("auth-failed-banner", "SSHPROXY_AUTH_FAILED_BANNER"); err != nil { return err } @@ -124,6 +133,14 @@ func main() { fixPathCheckExists("auth-failed-banner") } + shellCreds := &syscall.Credential{} + if viper.GetInt64("shell-uid") > 0 { + shellCreds.Uid = uint32(viper.GetInt64("shell-uid")) + } + if viper.GetInt64("shell-gid") > 0 { + shellCreds.Gid = uint32(viper.GetInt64("shell-gid")) + } + apiURL := fmt.Sprintf("https://%s:%d", viper.GetString("apihost"), viper.GetInt("apiport")) auth := newAuthHandler(apiURL, viper.GetString("apikey")) sshConfig := &ssh.ServerConfig{ @@ -150,6 +167,7 @@ func main() { viper.GetString("dir"), viper.GetString("shell"), viper.GetBool("allow-env"), + shellCreds, sshConfig, func(err error, tags map[string]string) { log.Printf("ERROR: %s", err) diff --git a/sshproxy.go b/sshproxy.go index 03d7a10..7a50e62 100644 --- a/sshproxy.go +++ b/sshproxy.go @@ -42,6 +42,7 @@ type Server struct { keyDir string config *ssh.ServerConfig shell string + shellCreds *syscall.Credential passEnv bool errorHandler ErrorHandler } @@ -53,11 +54,12 @@ type ErrorHandler func(error, map[string]string) // and an ssh.ServerConfig. If no ServerConfig is provided, then // ServerConfig.NoClientAuth is set to true. ed25519, rsa, ecdsa and dsa // keys are loaded, and generated if they do not exist. Returns a new Server. -func New(keyDir, shell string, passEnv bool, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) { +func New(keyDir, shell string, passEnv bool, shellCreds *syscall.Credential, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) { s := &Server{ keyDir: keyDir, config: sshConfig, shell: shell, + shellCreds: shellCreds, passEnv: passEnv, errorHandler: errorHandler, } @@ -307,6 +309,10 @@ func (s *Server) launchCommand(channel ssh.Channel, cmd *exec.Cmd, terminal *pty } } + if s.shellCreds != nil { + cmd.SysProcAttr = &syscall.SysProcAttr{Credential: s.shellCreds} + } + if terminal != nil { err := terminal.Start(cmd) if err != nil { From 697518d1705f0bc97df1127b18aaafa97536538e Mon Sep 17 00:00:00 2001 From: "resin-io-versionbot[bot]" Date: Mon, 10 Jul 2017 11:37:25 +0000 Subject: [PATCH 2/2] v1.4.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a6346d..39d3229 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! This project adheres to [Semantic Versioning](http://semver.org/). +## v1.4.0 - 2017-07-10 + +* Add support for running shell with alternative credentials [Will Boyce] + ## v1.3.0 - 2017-06-20 * Reflect command exit status in 'exit-status' request [Will Boyce]