Files
coder/cli/configssh_other.go
Steven Masley 0f505aa4da chore: unhide flag to force unix filepaths in config-ssh (#25142)
Docs now include this flag. This flag is now also viewable in linux/mac
despite it effectively being a `no-op`.

Closes https://github.com/coder/coder/issues/24205
2026-05-13 14:59:33 -05:00

35 lines
1.4 KiB
Go

//go:build !windows
package cli
import (
"strings"
"golang.org/x/xerrors"
)
// sshConfigMatchExecEscape prepares the path for use in `Match exec` statement.
//
// OpenSSH parses the Match line with a very simple tokenizer that accepts "-enclosed strings for the exec command, and
// has no supported escape sequences for ". This means we cannot include " within the command to execute.
func sshConfigMatchExecEscape(path string) (string, error) {
// This is unlikely to ever happen, but newlines are allowed on
// certain filesystems, but cannot be used inside ssh config.
if strings.ContainsAny(path, "\n") {
return "", xerrors.Errorf("invalid path: %s", path)
}
// Quotes are allowed in path names on unix-like file systems, but OpenSSH's parsing of `Match exec` doesn't allow
// them.
if strings.Contains(path, `"`) {
return "", xerrors.Errorf("path must not contain quotes: %q", path)
}
// OpenSSH passes the match exec string directly to the user's shell. sh, bash and zsh accept spaces, tabs and
// backslashes simply escaped by a `\`. It's hard to predict exactly what more exotic shells might do, but this
// should work for macOS and most Linux distros in their default configuration.
path = strings.ReplaceAll(path, `\`, `\\`) // must be first, since later replacements add backslashes.
path = strings.ReplaceAll(path, " ", "\\ ")
path = strings.ReplaceAll(path, "\t", "\\\t")
return path, nil
}