Skip to content

Commit

Permalink
User experience enhancements for OpenSSH options.
Browse files Browse the repository at this point in the history
Support key=value syntax for OpenSSH options and show help if the -o
flag is in the wrong place.
  • Loading branch information
russjones committed Jan 30, 2019
1 parent 1265d4c commit 6d78d98
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
14 changes: 13 additions & 1 deletion tool/tsh/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,23 @@ func parseOptions(opts []string) (Options, error) {
}

func splitOption(option string) (string, string, error) {
parts := strings.Fields(option)
parts := strings.FieldsFunc(option, fieldsFunc)

if len(parts) != 2 {
return "", "", trace.BadParameter("invalid format for option")
}

return parts[0], parts[1], nil
}

// fieldsFunc splits key-value pairs off ' ' and '='.
func fieldsFunc(c rune) bool {
switch {
case c == ' ':
return true
case c == '=':
return true
default:
return false
}
}
9 changes: 7 additions & 2 deletions tool/tsh/tsh.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ import (
"github.com/gravitational/teleport/lib/session"
"github.com/gravitational/teleport/lib/sshutils"
"github.com/gravitational/teleport/lib/utils"

"github.com/gravitational/kingpin"
"github.com/gravitational/trace"

gops "github.com/google/gops/agent"
Expand Down Expand Up @@ -181,6 +183,9 @@ func Run(args []string, underTest bool) {
app.Flag("proxy", "SSH proxy address").Envar("TELEPORT_PROXY").StringVar(&cf.Proxy)
app.Flag("nocache", "do not cache cluster discovery locally").Hidden().BoolVar(&cf.NoCache)
app.Flag("user", fmt.Sprintf("SSH proxy user [%s]", localUser)).Envar("TELEPORT_USER").StringVar(&cf.Username)
app.Flag("option", "").Short('o').Hidden().AllowDuplicate().PreAction(func(ctx *kingpin.ParseContext) error {
return trace.BadParameter("invalid flag, perhaps you want to use this flag as tsh ssh -o?")
}).String()

app.Flag("ttl", "Minutes to live for a SSH session").Int32Var(&cf.MinsToLive)
app.Flag("identity", "Identity file").Short('i').StringVar(&cf.IdentityFileIn)
Expand All @@ -206,7 +211,7 @@ func Run(args []string, underTest bool) {
ssh.Flag("local", "Execute command on localhost after connecting to SSH node").Default("false").BoolVar(&cf.LocalExec)
ssh.Flag("tty", "Allocate TTY").Short('t').BoolVar(&cf.Interactive)
ssh.Flag("cluster", clusterHelp).Envar(clusterEnvVar).StringVar(&cf.SiteName)
ssh.Flag("option", "OpenSSH options in the format used in the configuration file").Short('o').StringsVar(&cf.Options)
ssh.Flag("option", "OpenSSH options in the format used in the configuration file").Short('o').AllowDuplicate().StringsVar(&cf.Options)

// join
join := app.Command("join", "Join the active SSH session")
Expand Down Expand Up @@ -235,7 +240,7 @@ func Run(args []string, underTest bool) {
// login logs in with remote proxy and obtains a "session certificate" which gets
// stored in ~/.tsh directory
login := app.Command("login", "Log in to a cluster and retrieve the session certificate")
login.Flag("out", "Identity output").Short('o').StringVar(&cf.IdentityFileOut)
login.Flag("out", "Identity output").Short('o').AllowDuplicate().StringVar(&cf.IdentityFileOut)
login.Flag("format", fmt.Sprintf("Identity format [%s] or %s (for OpenSSH compatibility)",
client.DefaultIdentityFormat,
client.IdentityFormatOpenSSH)).Default(string(client.DefaultIdentityFormat)).StringVar((*string)(&cf.IdentityFormat))
Expand Down
13 changes: 13 additions & 0 deletions tool/tsh/tsh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,19 @@ func (s *MainTestSuite) TestOptions(c *check.C) {
StrictHostKeyChecking: true,
},
},
// Valid
{
inOptions: []string{
"AddKeysToAgent=yes",
},
outError: false,
outOptions: Options{
AddKeysToAgent: true,
ForwardAgent: false,
RequestTTY: false,
StrictHostKeyChecking: true,
},
},
// Invalid value.
{
inOptions: []string{
Expand Down

0 comments on commit 6d78d98

Please sign in to comment.