-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2127 from sschaap/feature/windows-openssh
Support for Windows OpenSSH agent forwarding
- Loading branch information
Showing
3 changed files
with
114 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// +build !windows | ||
|
||
package sshprovider | ||
|
||
import ( | ||
"github.com/pkg/errors" | ||
) | ||
|
||
func getFallbackAgentPath() (string, error) { | ||
return "", errors.Errorf("make sure SSH_AUTH_SOCK is set") | ||
} | ||
|
||
func getWindowsPipeDialer(path string) *socketDialer { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// +build windows | ||
|
||
package sshprovider | ||
|
||
import ( | ||
"net" | ||
"regexp" | ||
"strings" | ||
|
||
"github.com/Microsoft/go-winio" | ||
"github.com/pkg/errors" | ||
"golang.org/x/sys/windows" | ||
) | ||
|
||
// Returns the Windows OpenSSH agent named pipe path, but | ||
// only if the agent is running. Returns an error otherwise. | ||
func getFallbackAgentPath() (string, error) { | ||
// Windows OpenSSH agent uses a named pipe rather | ||
// than a UNIX socket. These pipes do not play nice | ||
// with os.Stat (which tries to open its target), so | ||
// use a FindFirstFile syscall to check for existence. | ||
var fd windows.Win32finddata | ||
|
||
path := `\\.\pipe\openssh-ssh-agent` | ||
pathPtr, _ := windows.UTF16PtrFromString(path) | ||
handle, err := windows.FindFirstFile(pathPtr, &fd) | ||
|
||
if err != nil { | ||
msg := "Windows OpenSSH agent not available at %s." + | ||
" Enable the SSH agent service or set SSH_AUTH_SOCK." | ||
return "", errors.Errorf(msg, path) | ||
} | ||
|
||
_ = windows.CloseHandle(handle) | ||
|
||
return path, nil | ||
} | ||
|
||
// Returns true if the path references a named pipe. | ||
func isWindowsPipePath(path string) bool { | ||
// If path matches \\*\pipe\* then it references a named pipe | ||
// and requires winio.DialPipe() rather than DialTimeout("unix"). | ||
// Slashes and backslashes may be used interchangeably in the path. | ||
// Path separators may consist of multiple consecutive (back)slashes. | ||
pipePattern := strings.ReplaceAll("^[/]{2}[^/]+[/]+pipe[/]+", "/", `\\/`) | ||
ok, _ := regexp.MatchString(pipePattern, path) | ||
return ok | ||
} | ||
|
||
func getWindowsPipeDialer(path string) *socketDialer { | ||
if isWindowsPipePath(path) { | ||
return &socketDialer{path: path, dialer: windowsPipeDialer} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func windowsPipeDialer(path string) (net.Conn, error) { | ||
return winio.DialPipe(path, nil) | ||
} |