Skip to content

Commit 44d19f1

Browse files
committed
add support for macOS & Linux
1 parent 69112fa commit 44d19f1

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

cli/configssh_other.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,34 @@
22

33
package cli
44

5+
import (
6+
"strings"
7+
8+
"golang.org/x/xerrors"
9+
)
10+
511
var hideForceUnixSlashes = true
12+
13+
// sshConfigMatchExecEscape prepares the path for use in `Match exec` statement.
14+
//
15+
// OpenSSH parses the Match line with a very simple tokenizer that accepts "-enclosed strings for the exec command, and
16+
// has no supported escape sequences for ". This means we cannot include " within the command to execute.
17+
func sshConfigMatchExecEscape(path string) (string, error) {
18+
// This is unlikely to ever happen, but newlines are allowed on
19+
// certain filesystems, but cannot be used inside ssh config.
20+
if strings.ContainsAny(path, "\n") {
21+
return "", xerrors.Errorf("invalid path: %s", path)
22+
}
23+
// Quotes are allowed in path names on unix-like file systems, but OpenSSH's parsing of `Match exec` doesn't allow
24+
// them.
25+
if strings.Contains(path, `"`) {
26+
return "", xerrors.Errorf("path must not contain quotes: %q", path)
27+
}
28+
29+
// OpenSSH passes the match exec string directly to the user's shell. sh, bash and zsh accept spaces and tabs
30+
// simply escaped by a `\`. It's hard to predict exactly what more exotic shells might do, but this should work for
31+
// macOS and most Linux distros in their default configuration.
32+
path = strings.ReplaceAll(path, " ", "\\ ")
33+
path = strings.ReplaceAll(path, "\t", "\\\t")
34+
return path, nil
35+
}

0 commit comments

Comments
 (0)