Skip to content

Commit

Permalink
Merge pull request #54 from balena-io/env-whitelist
Browse files Browse the repository at this point in the history
allow specifying a whitelist of env vars to pass from client
  • Loading branch information
wrboyce authored Jul 25, 2019
2 parents df5bc2e + a987f39 commit 457bb2e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 11 deletions.
5 changes: 3 additions & 2 deletions balena/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"os"
"path"
"runtime"
"strings"
"syscall"

"github.com/balena-io/sshproxy"
Expand All @@ -49,7 +50,7 @@ func init() {
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)")
pflag.CommandLine.StringP("allow-env", "E", "", "List of environment variables to pass from client to shell (default: None)")
pflag.CommandLine.StringP("sentry-dsn", "S", "", "Sentry DSN for error reporting")
pflag.CommandLine.IntP("verbosity", "v", 1, "Set verbosity level (0 = quiet, 1 = normal, 2 = verbose, 3 = debug, default: 1)")
pflag.CommandLine.BoolP("version", "", false, "Display version and exit")
Expand Down Expand Up @@ -179,7 +180,7 @@ func main() {
server, err := sshproxy.New(
viper.GetString("dir"),
viper.GetString("shell"),
viper.GetBool("allow-env"),
strings.Split(viper.GetString("allow-env"), ","),
shellCreds,
viper.GetInt("verbosity"),
sshConfig,
Expand Down
22 changes: 13 additions & 9 deletions sshproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Server struct {
config *ssh.ServerConfig
shell string
shellCreds *syscall.Credential
passEnv bool
envWhitelist map[string]bool
errorHandler ErrorHandler
verbosity int
}
Expand All @@ -57,13 +57,13 @@ 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, shellCreds *syscall.Credential, verbosity int, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) {
func New(keyDir, shell string, envWhitelist []string, shellCreds *syscall.Credential, verbosity int, sshConfig *ssh.ServerConfig, errorHandler ErrorHandler) (*Server, error) {
s := &Server{
keyDir: keyDir,
config: sshConfig,
shell: shell,
shellCreds: shellCreds,
passEnv: passEnv,
envWhitelist: make(map[string]bool),
errorHandler: errorHandler,
verbosity: verbosity,
}
Expand All @@ -72,6 +72,9 @@ func New(keyDir, shell string, passEnv bool, shellCreds *syscall.Credential, ver
NoClientAuth: true,
}
}
for _, envKey := range envWhitelist {
s.envWhitelist[envKey] = true
}
for _, keyType := range []string{"ed25519", "rsa", "ecdsa", "dsa"} {
if err := s.addHostKey(keyType); err != nil {
return nil, err
Expand Down Expand Up @@ -211,15 +214,16 @@ func (s *Server) handleRequests(reqs <-chan *ssh.Request, channel ssh.Channel, c
for req := range reqs {
switch req.Type {
case "env":
if s.passEnv {
// append client env to the command environment
keyLen := binary.BigEndian.Uint32(req.Payload[:4])
valLen := binary.BigEndian.Uint32(req.Payload[keyLen+4 : keyLen+8])
key := string(req.Payload[4 : keyLen+4])
// append client env to the command environment
keyLen := binary.BigEndian.Uint32(req.Payload[:4])
valLen := binary.BigEndian.Uint32(req.Payload[keyLen+4 : keyLen+8])
key := string(req.Payload[4 : keyLen+4])
_, ok := s.envWhitelist[key]
if ok {
val := string(req.Payload[keyLen+8 : keyLen+valLen+8])
env = append(env, fmt.Sprintf("%s=%s", key, val))
}
if err := req.Reply(s.passEnv, nil); err != nil {
if err := req.Reply(ok, nil); err != nil {
return err
}
case "pty-req":
Expand Down

0 comments on commit 457bb2e

Please sign in to comment.