[easyssh] fix: panic when using ssh-agent (appleboy/easyssh-proxy#42)

Before changes:

```sh
$ # This is what `keychain --eval --inherit any` does on Ubuntu.
$ # https://www.funtoo.org/Keychain
$ export SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
$ go build example/ssh/ssh.go
$ ./ssh
panic: Can't run remote command: ssh: handshake failed: agent: client error: write unix @->/run/user/1000/keyring/ssh: use of closed network connection

goroutine 1 [running]:
main.main()
	/home/wsh/go/src/github.com/wataash/easyssh-proxy/example/ssh/ssh.go:32 +0x2d3
```

Error message `write unix @->/run/user/1000/keyring/ssh: use of closed network connection` comes from [`Write()`](https://github.com/golang/crypto/blob/2b6c08872f4/ssh/agent/client.go#L277) where `SSH_AUTH_SOCK` is already `Close()`ed.

After changes:

```sh
$ export SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
$ go build example/ssh/ssh.go
$ ./ssh
github.com/wataash/easyssh-proxy
command-line-arguments
don is : true stdout is : total 640
drwxr-xr-x  68 wsh  wsh   4096 10月 16 21:25 .
drwxr-xr-x   3 root root  4096  9月 12 08:39 ..
drwxr-xr-x   2 wsh  wsh   4096  9月 20 20:48 .android
...
-rw-rw-r--   1 wsh  wsh    202  9月 12 19:51 .zshrc
 ;   stderr is : Identity added: /home/wsh/.ssh/id_rsa (/home/wsh/.ssh/id_rsa)
Identity added: /home/wsh/.ssh/id_ed25519 (wsh@wsh9b)

```

https://github.com/appleboy/drone-ssh/commit/9b697286281
This commit is contained in:
Wataru Ashihara 2018-10-17 23:39:14 +09:00 committed by Wataru Ashihara
parent b5fc545ce2
commit 097a640e79
No known key found for this signature in database
GPG Key ID: CE9EC2D5AE43DEFA

View File

@ -67,7 +67,12 @@ func getKeyFile(keypath string) (ssh.Signer, error) {
return pubkey, nil
}
func getSSHConfig(config DefaultConfig) *ssh.ClientConfig {
// returns *ssh.ClientConfig and io.Closer.
// if io.Closer is not nil, io.Closer.Close() should be called when
// *ssh.ClientConfig is no longer used.
func getSSHConfig(config DefaultConfig) (*ssh.ClientConfig, io.Closer) {
var sshAgent io.Closer
// auths holds the detected ssh auth methods
auths := []ssh.AuthMethod{}
@ -93,7 +98,6 @@ func getSSHConfig(config DefaultConfig) *ssh.ClientConfig {
if sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK")); err == nil {
auths = append(auths, ssh.PublicKeysCallback(agent.NewClient(sshAgent).Signers))
defer sshAgent.Close()
}
return &ssh.ClientConfig{
@ -101,7 +105,7 @@ func getSSHConfig(config DefaultConfig) *ssh.ClientConfig {
User: config.User,
Auth: auths,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
}, sshAgent
}
// Connect to remote server using MakeConfig struct and returns *ssh.Session
@ -109,23 +113,29 @@ func (ssh_conf *MakeConfig) Connect() (*ssh.Session, error) {
var client *ssh.Client
var err error
targetConfig := getSSHConfig(DefaultConfig{
targetConfig, closer := getSSHConfig(DefaultConfig{
User: ssh_conf.User,
Key: ssh_conf.Key,
KeyPath: ssh_conf.KeyPath,
Password: ssh_conf.Password,
Timeout: ssh_conf.Timeout,
})
if closer != nil {
defer closer.Close()
}
// Enable proxy command
if ssh_conf.Proxy.Server != "" {
proxyConfig := getSSHConfig(DefaultConfig{
proxyConfig, closer := getSSHConfig(DefaultConfig{
User: ssh_conf.Proxy.User,
Key: ssh_conf.Proxy.Key,
KeyPath: ssh_conf.Proxy.KeyPath,
Password: ssh_conf.Proxy.Password,
Timeout: ssh_conf.Proxy.Timeout,
})
if closer != nil {
defer closer.Close()
}
proxyClient, err := ssh.Dial("tcp", net.JoinHostPort(ssh_conf.Proxy.Server, ssh_conf.Proxy.Port), proxyConfig)
if err != nil {