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

Allow vault ssh to work with single ssh args like -v #4825

Merged
merged 1 commit into from
Jul 16, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions command/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -761,12 +761,30 @@ func (c *SSHCommand) defaultRole(mountPoint, ip string) (string, error) {
}
}

func (c *SSHCommand) isSingleSSHArg(arg string) bool {
// list of single SSH arguments is taken from
// https://github.com/openssh/openssh-portable/blob/28013759f09ed3ebf7e8335e83a62936bd7a7f47/ssh.c#L204
singleArgs := []string{
"4", "6", "A", "a", "C", "f", "G", "g", "K", "k", "M", "N", "n", "q",
"s", "T", "t", "V", "v", "X", "x", "Y", "y",
}

// We want to get the first character after the dash. This is so args like -vvv are picked up as just being -v
flag := string(arg[1])

for _, a := range singleArgs {
if flag == a {
return true
}
}
return false
}

// Finds the hostname, username (optional) and port (optional) from any valid ssh command
// Supports usrname@hostname but also specifying valid ssh flags like -o User=username,
// -o Port=2222 and -p 2222 anywhere in the command
func (c *SSHCommand) parseSSHCommand(args []string) (hostname string, username string, port string, err error) {
lastArg := ""

for _, i := range args {
arg := lastArg
lastArg = ""
Expand Down Expand Up @@ -807,9 +825,12 @@ func (c *SSHCommand) parseSSHCommand(args []string) (hostname string, username s
continue
}

// If this is an ssh argument we want to look at the value
// If this is an ssh argument with a value we want to look at it in the next loop
if strings.HasPrefix(i, "-") {
lastArg = i
// If this isn't a single SSH arg we want to store the flag to we can look at the value next loop
if !c.isSingleSSHArg(i) {
lastArg = i
}
continue
}

Expand Down
61 changes: 61 additions & 0 deletions command/ssh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,31 @@ func TestParseSSHCommand(t *testing.T) {
"",
nil,
},
{
"Allow single args which don't have a value",
[]string{
"-v",
"hostname",
},
"hostname",
"",
"",
nil,
},
{
"Allow single args before and after the hostname and command",
[]string{
"-v",
"hostname",
"-v",
"command",
"-v",
},
"hostname",
"",
"",
nil,
},
}

for _, test := range tests {
Expand All @@ -154,3 +179,39 @@ func TestParseSSHCommand(t *testing.T) {
})
}
}

func TestIsSingleSSHArg(t *testing.T) {
t.Parallel()

_, cmd := testSSHCommand(t)
var tests = []struct {
name string
arg string
want bool
}{
{
"-v is a single ssh arg",
"-v",
true,
},
{
"-o is NOT a single ssh arg",
"-o",
false,
},
{
"Repeated args like -vvv is still a single ssh arg",
"-vvv",
true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := cmd.isSingleSSHArg(test.arg)
if got != test.want {
t.Errorf("arg %q got %v want %v", test.arg, got, test.want)
}
})
}
}