Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v13] Fix SSH_* env var check for headless #28922

Merged
merged 1 commit into from Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 26 additions & 30 deletions tool/tsh/tsh.go
Expand Up @@ -1011,7 +1011,7 @@ func Run(ctx context.Context, args []string, opts ...cliOption) error {
}

// configs
setEnvFlags(&cf, os.Getenv)
setEnvFlags(&cf)

confOptions, err := loadAllConfigs(cf)
if err != nil {
Expand Down Expand Up @@ -3455,9 +3455,22 @@ func loadClientConfigFromCLIConf(cf *CLIConf, proxy string) (*client.Config, err
cf.AuthConnector = constants.HeadlessConnector
}

// When using Headless, user must be provided explicitly.
if cf.AuthConnector == constants.HeadlessConnector && !cf.ExplicitUsername {
return nil, trace.BadParameter("user must be set explicitly for headless login with the --user flag or $TELEPORT_USER env variable")
if cf.AuthConnector == constants.HeadlessConnector {
// When using Headless, check for missing proxy/user/cluster values from the teleport session env variables.
if cf.Proxy == "" {
cf.Proxy = os.Getenv(teleport.SSHSessionWebProxyAddr)
}
if cf.Username == "" {
cf.Username = os.Getenv(teleport.SSHTeleportUser)
}
if cf.SiteName == "" {
cf.SiteName = os.Getenv(teleport.SSHTeleportClusterName)
}

// When using Headless, user must be provided.
if cf.Username == "" {
return nil, trace.BadParameter("user must be provided for headless login")
}
}

if err := tryLockMemory(cf); err != nil {
Expand Down Expand Up @@ -3570,7 +3583,7 @@ func loadClientConfigFromCLIConf(cf *CLIConf, proxy string) (*client.Config, err
c.ForwardAgent = client.ForwardAgentYes
}

if err := setX11Config(c, cf, options, os.Getenv); err != nil {
if err := setX11Config(c, cf, options); err != nil {
log.WithError(err).Info("X11 forwarding is not properly configured, continuing without it.")
}

Expand Down Expand Up @@ -3745,11 +3758,11 @@ func parseMFAMode(mode string) (*mfaModeOpts, error) {
}

// setX11Config sets X11 config using CLI and SSH option flags.
func setX11Config(c *client.Config, cf *CLIConf, o Options, fn envGetter) error {
func setX11Config(c *client.Config, cf *CLIConf, o Options) error {
// X11 forwarding can be enabled with -X, -Y, or -oForwardX11=yes
c.EnableX11Forwarding = cf.X11ForwardingUntrusted || cf.X11ForwardingTrusted || o.ForwardX11

if c.EnableX11Forwarding && fn(x11.DisplayEnv) == "" {
if c.EnableX11Forwarding && os.Getenv(x11.DisplayEnv) == "" {
c.EnableX11Forwarding = false
return trace.BadParameter("$DISPLAY must be set for X11 forwarding")
}
Expand Down Expand Up @@ -4619,45 +4632,28 @@ func serializeEnvironment(profile *client.ProfileStatus, format string) (string,
return string(out), trace.Wrap(err)
}

// envGetter is used to read in the environment. In production "os.Getenv"
// is used.
type envGetter func(string) string

// setEnvFlags sets flags that can be set via environment variables.
func setEnvFlags(cf *CLIConf, getEnv envGetter) {
func setEnvFlags(cf *CLIConf) {
// these can only be set with env vars.
if homeDir := getEnv(types.HomeEnvVar); homeDir != "" {
if homeDir := os.Getenv(types.HomeEnvVar); homeDir != "" {
cf.HomePath = path.Clean(homeDir)
}
if configPath := getEnv(globalTshConfigEnvVar); configPath != "" {
if configPath := os.Getenv(globalTshConfigEnvVar); configPath != "" {
cf.GlobalTshConfigPath = path.Clean(configPath)
}

// prioritize CLI input for the rest.
if cf.SiteName == "" {
// check cluster env variables in order of priority.
if clusterName := getEnv(clusterEnvVar); clusterName != "" {
if clusterName := os.Getenv(clusterEnvVar); clusterName != "" {
cf.SiteName = clusterName
} else if clusterName = getEnv(siteEnvVar); clusterName != "" {
} else if clusterName = os.Getenv(siteEnvVar); clusterName != "" {
cf.SiteName = clusterName
}
}

if cf.KubernetesCluster == "" {
cf.KubernetesCluster = getEnv(kubeClusterEnvVar)
}

// When using Headless, check for missing proxy/user/cluster values from the teleport session env variables.
if cf.Headless || cf.AuthConnector == constants.HeadlessConnector {
if cf.Proxy == "" {
cf.Proxy = getEnv(teleport.SSHSessionWebProxyAddr)
}
if cf.Username == "" {
cf.Username = getEnv(teleport.SSHTeleportUser)
}
if cf.SiteName == "" {
cf.SiteName = getEnv(teleport.SSHTeleportClusterName)
}
cf.KubernetesCluster = os.Getenv(kubeClusterEnvVar)
}
}

Expand Down