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

This commit is contained in:
Michael Russell 2018-07-16 16:11:56 +02:00 committed by Jeff Mitchell
parent 8fb804ecce
commit b6dfe372fd
2 changed files with 85 additions and 3 deletions

View File

@ -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 = ""
@ -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
}

View File

@ -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 {
@ -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)
}
})
}
}