Ctrl K
ComunidadGuías…

cli/configssh_windows.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
//go:build windows

package cli

import (
	"fmt"
	"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.
//
// To make matters worse, on Windows, OpenSSH passes the string directly to cmd.exe for execution, and as far as I can
// tell, the only supported way to call a path that has spaces in it is to surround it with ".
//
// So, we can't actually include " directly, but here is a horrible workaround:
//
// "for /f %%a in ('powershell.exe -Command [char]34') do @cmd.exe /c %%aC:\Program Files\Coder\bin\coder.exe%%a connect exists %h"
//
// The key insight here is to store the character " in a variable (%a in this case, but the % itself needs to be
// escaped, so it becomes %%a), and then use that variable to construct the double-quoted path:
//
// %%aC:\Program Files\Coder\bin\coder.exe%%a.
//
// How do we generate a single " character without actually using that character? I couldn't find any command in cmd.exe
// to do it, but powershell.exe can convert ASCII to characters like this: `[char]34` (where 34 is the code point for ").
//
// Other notes:
//   - @ in `@cmd.exe` suppresses echoing it, so you don't get this command printed
//   - we need another invocation of cmd.exe (e.g. `do @cmd.exe /c %%aC:\Program Files\Coder\bin\coder.exe%%a`). Without
//     it the double-quote gets interpreted as part of the path, and you get: '"C:\Program' is not recognized.
//     Constructing the string and then passing it to another instance of cmd.exe does this trick here.
//   - OpenSSH passes the `Match exec` command to cmd.exe regardless of whether the user has a unix-like shell like
//     git bash, so we don't have a `forceUnixPath` option like for the ProxyCommand which does respect the user's
//     configured shell on Windows.
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)
	}
	// Windows does not allow double-quotes or tabs in paths. If we get one it is an error.
	if strings.ContainsAny(path, "\"\t") {
		return "", xerrors.Errorf("path must not contain quotes or tabs: %q", path)
	}

	if strings.ContainsAny(path, " ") {
		// c.f. function comment for how this works.
		path = fmt.Sprintf("for /f %%%%a in ('powershell.exe -Command [char]34') do @cmd.exe /c %%%%a%s%%%%a", path) //nolint:gocritic // We don't want %q here.
	}
	return path, nil
}