Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions pageant_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions sshagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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") != ""
}
32 changes: 27 additions & 5 deletions sshagent_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,28 @@ import (
"errors"
"io"
"net"
"os"
"strings"
"sync"

"github.com/Microsoft/go-winio"
"golang.org/x/crypto/ssh/agent"
)

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
}
Expand All @@ -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 {
Expand Down