Skip to content

Commit 4fbfc9f

Browse files
committed
Added support of ssh_agent and passphrase
1 parent bfa903e commit 4fbfc9f

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

helper.go

+34-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ package vssh
55

66
import (
77
"fmt"
8-
"io/ioutil"
9-
108
"golang.org/x/crypto/ssh"
9+
"golang.org/x/crypto/ssh/agent"
10+
"io/ioutil"
11+
"net"
1112
)
1213

1314
// GetConfigPEM returns SSH configuration that uses the given private key.
@@ -26,6 +27,37 @@ func GetConfigPEM(user, keyFile string) (*ssh.ClientConfig, error) {
2627
return getConfig(user, ssh.PublicKeys(signer)), nil
2728
}
2829

30+
// GetConfigPEMWithPassphrase returns SSH configuration that uses the given private key and passphrase.
31+
func GetConfigPEMWithPassphrase(user, keyFile string, passphrase string) (*ssh.ClientConfig, error) {
32+
key, err := ioutil.ReadFile(keyFile)
33+
if err != nil {
34+
return nil, fmt.Errorf("unable to read private key: %v", err)
35+
}
36+
37+
signer, err := ssh.ParsePrivateKeyWithPassphrase(key, []byte(passphrase))
38+
if err != nil {
39+
return nil, fmt.Errorf("unable to parse private key: %v", err)
40+
}
41+
42+
return getConfig(user, ssh.PublicKeys(signer)), nil
43+
}
44+
45+
// GetConfigSSHAgent returns SSH configuration from SSH Agent.
46+
// default socket can get from env: os.Getenv("SSH_AUTH_SOCK")
47+
func GetConfigSSHAgent(user, socket string) (*ssh.ClientConfig, error) {
48+
conn, err := net.Dial("unix", socket)
49+
if err != nil {
50+
return nil, fmt.Errorf("unable to connect to ssh agent: %v", err)
51+
}
52+
agentconn := agent.NewClient(conn)
53+
signers, err := agentconn.Signers()
54+
if err != nil {
55+
return nil, fmt.Errorf("unable to get signers: %v", err)
56+
}
57+
58+
return getConfig(user, ssh.PublicKeys(signers...)), nil
59+
}
60+
2961
// GetConfigUserPass returns SSH configuration that uses the given
3062
// username and password.
3163
func GetConfigUserPass(user, password string) *ssh.ClientConfig {

vssh_test.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestForceReConn(t *testing.T) {
1616
t.Error(err)
1717
}
1818

19-
vs.ForceReConn("127.0.0.1:22")
19+
_ = vs.ForceReConn("127.0.0.1:22")
2020
if len(vs.actionQ) != 2 {
2121
t.Fatal("expect to have two tasks but got", len(vs.actionQ))
2222
}
@@ -140,3 +140,22 @@ func TestGetConfigPEM(t *testing.T) {
140140
t.Error("expect error but nil")
141141
}
142142
}
143+
144+
func TestGetConfigPEMWithPassphrase(t *testing.T) {
145+
_, err := GetConfigPEMWithPassphrase("vssh", "notexitfile", "pass1")
146+
if err == nil {
147+
t.Error("expect error but nil")
148+
}
149+
150+
_, err = GetConfigPEMWithPassphrase("vssh", "vssh.go", "pass2")
151+
if err == nil {
152+
t.Error("expect error but nil")
153+
}
154+
}
155+
156+
func TestGetConfigSSHAgent(t *testing.T) {
157+
_, err := GetConfigSSHAgent("root", "/path/to/socket/file")
158+
if err == nil {
159+
t.Error("expect error but nil")
160+
}
161+
}

0 commit comments

Comments
 (0)