sftp: add support for about and hashsum on windows server

Windows shells like cmd and powershell needs to use different quoting/escaping
of strings and paths than the unix shell, and also absolute paths must be fixed
by removing leading slash that the POSIX formatted paths have
(e.g. /C:/Users does not work in shell, it must be converted to C:/Users).

Tries to autodetect shell type (cmd, powershell, unix) on first use.

Implemented default builtin powershell functions for hashsum and about when remote
shell is powershell.

See #5763

Fixes #5758
This commit is contained in:
albertony 2021-10-27 17:01:54 +02:00
parent 218bf2183d
commit b4091f282a
3 changed files with 436 additions and 89 deletions

View file

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestShellEscape(t *testing.T) {
func TestShellEscapeUnix(t *testing.T) {
for i, test := range []struct {
unescaped, escaped string
}{
@ -20,7 +20,44 @@ func TestShellEscape(t *testing.T) {
{"/test/\n", "/test/'\n'"},
{":\"'", ":\\\"\\'"},
} {
got := shellEscape(test.unescaped)
got, err := quoteOrEscapeShellPath("unix", test.unescaped)
assert.NoError(t, err)
assert.Equal(t, test.escaped, got, fmt.Sprintf("Test %d unescaped = %q", i, test.unescaped))
}
}
func TestShellEscapeCmd(t *testing.T) {
for i, test := range []struct {
unescaped, escaped string
ok bool
}{
{"", "\"\"", true},
{"c:/this/is/harmless", "\"c:/this/is/harmless\"", true},
{"c:/test&notepad", "\"c:/test&notepad\"", true},
{"c:/test\"&\"notepad", "", false},
} {
got, err := quoteOrEscapeShellPath("cmd", test.unescaped)
if test.ok {
assert.NoError(t, err)
assert.Equal(t, test.escaped, got, fmt.Sprintf("Test %d unescaped = %q", i, test.unescaped))
} else {
assert.Error(t, err)
}
}
}
func TestShellEscapePowerShell(t *testing.T) {
for i, test := range []struct {
unescaped, escaped string
}{
{"", "''"},
{"c:/this/is/harmless", "'c:/this/is/harmless'"},
{"c:/test&notepad", "'c:/test&notepad'"},
{"c:/test\"&\"notepad", "'c:/test\"&\"notepad'"},
{"c:/test'&'notepad", "'c:/test''&''notepad'"},
} {
got, err := quoteOrEscapeShellPath("powershell", test.unescaped)
assert.NoError(t, err)
assert.Equal(t, test.escaped, got, fmt.Sprintf("Test %d unescaped = %q", i, test.unescaped))
}
}