-
Notifications
You must be signed in to change notification settings - Fork 151
/
ssh_windows.go
56 lines (48 loc) · 1.74 KB
/
ssh_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package ssh
import (
"fmt"
"os"
"path/filepath"
"github.com/pkg/errors"
)
// commandSearchPaths specifies locations on Windows where we might find ssh.exe
// and scp.exe binaries.
var commandSearchPaths = []string{
// TODO: Add the PowerShell OpenSSH paths at the top of this list once
// there's a usable release.
`C:\Program Files\Git\usr\bin`,
`C:\Program Files (x86)\Git\usr\bin`,
`C:\msys32\usr\bin`,
`C:\msys64\usr\bin`,
`C:\cygwin\bin`,
`C:\cygwin64\bin`,
}
// commandNamed searches for a command with the specified name in a special set
// of whitelisted directories.
func commandNamed(name string) (string, error) {
// TODO: When the OpenSSH landscape on Windows eventually stablizes (i.e.
// once the PowerShell team releases a stable and usable OpenSSH version),
// we might try to do an exec.LookPath call to let any binary in the user's
// path be picked up first. We'd still need the well-known paths though,
// since they might not be in the user's path.
// Scan well-known directories where we might find a viable binary.
for _, path := range commandSearchPaths {
target := filepath.Join(path, fmt.Sprintf("%s.exe", name))
// TODO: Should we inspect the information used by stat to ensure this
// is a file? No real need to check executability, anything with an exe
// extension on Windows shows up as executable.
if _, err := os.Stat(target); err == nil {
return target, nil
}
}
// Failure.
return "", errors.New("unable to locate command")
}
// scpCommandName returns the name of or path to the scp command.
func scpCommandName() (string, error) {
return commandNamed("scp")
}
// sshCommandName returns the name of or path to the ssh command.
func sshCommandName() (string, error) {
return commandNamed("ssh")
}