diff --git a/pageant_windows.go b/pageant_windows.go index 1608e54..072b81b 100644 --- a/pageant_windows.go +++ b/pageant_windows.go @@ -36,7 +36,7 @@ import ( "golang.org/x/sys/windows" ) -// Maximum size of message can be sent to pageant +// Maximum size of message can be sent to pageant. const MaxMessageLen = 8192 var ( @@ -76,8 +76,6 @@ func winAPI(dll *windows.LazyDLL, funcName string) func(...uintptr) (uintptr, ui } // Query sends message msg to Pageant and returns response or error. -// 'msg' is raw agent request with length prefix -// Response is raw agent response with length prefix func query(msg []byte) ([]byte, error) { if len(msg) > MaxMessageLen { return nil, ErrMessageTooLong diff --git a/sshagent.go b/sshagent.go index 4a4ee30..f3bc509 100644 --- a/sshagent.go +++ b/sshagent.go @@ -28,7 +28,7 @@ import ( "golang.org/x/crypto/ssh/agent" ) -// New returns a new agent.Agent that uses a unix socket +// New returns a new agent.Agent that uses a unix socket. func New() (agent.Agent, net.Conn, error) { if !Available() { return nil, nil, errors.New("SSH agent requested but SSH_AUTH_SOCK not-specified") @@ -44,7 +44,7 @@ func New() (agent.Agent, net.Conn, error) { return agent.NewClient(conn), conn, nil } -// Available returns true is a auth socket is defined +// Available returns true if an auth socket is defined. func Available() bool { return os.Getenv("SSH_AUTH_SOCK") != "" } diff --git a/sshagent_windows.go b/sshagent_windows.go index 175d161..394cad6 100644 --- a/sshagent_windows.go +++ b/sshagent_windows.go @@ -26,6 +26,8 @@ import ( "errors" "io" "net" + "os" + "strings" "sync" "github.com/Microsoft/go-winio" @@ -33,15 +35,19 @@ import ( ) const ( - sshAgentPipe = `\\.\pipe\openssh-ssh-agent` + pipe = `\\.\pipe\` + openSSHAgentPipe = pipe + "openssh-ssh-agent" ) -// Available returns true if Pageant is running +// Available returns true if Pageant is running. func Available() bool { if pageantWindow() != 0 { return true } - conn, err := winio.DialPipe(sshAgentPipe, nil) + if sshAuthSock := os.Getenv("SSH_AUTH_SOCK"); sshAuthSock != "" { + return true + } + conn, err := winio.DialPipe(openSSHAgentPipe, nil) if err != nil { return false } @@ -50,18 +56,34 @@ func Available() bool { } // New returns a new agent.Agent and the (custom) connection it uses -// to communicate with a running pagent.exe instance (see README.md) +// to communicate with a running pagent.exe instance (see README.md). func New() (agent.Agent, net.Conn, error) { if pageantWindow() != 0 { return agent.NewClient(&conn{}), nil, nil } + + sshAgentPipe := openSSHAgentPipe + if sshAuthSock := os.Getenv("SSH_AUTH_SOCK"); sshAuthSock != "" { + conn, err := net.Dial("unix", sshAuthSock) + if err == nil { + return agent.NewClient(conn), conn, nil + } + + if !strings.HasPrefix(sshAuthSock, pipe) { + sshAuthSock = pipe + sshAuthSock + } + + sshAgentPipe = sshAuthSock + } + conn, err := winio.DialPipe(sshAgentPipe, nil) if err != nil { return nil, nil, errors.New( "SSH agent requested, but could not detect Pageant or Windows native SSH agent", ) } - return agent.NewClient(conn), nil, nil + + return agent.NewClient(conn), conn, nil } type conn struct {