-
Notifications
You must be signed in to change notification settings - Fork 0
/
sshagent.go
75 lines (65 loc) · 1.64 KB
/
sshagent.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package sshagent
import (
"io/ioutil"
"log"
"math/rand"
"net"
"os"
"strings"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)
// StartSSHAgentServer start an SSH Agent server and loads the given private key
func StartSSHAgentServer(sshAgent agent.Agent) (sshAuthSock string, error error) {
// Generate random filename
dir, err := ioutil.TempDir(os.TempDir(), "")
if err != nil {
log.Fatal(err)
}
sshAuthSock = dir + "/" + generateRandomString(8) + ".sock"
go func() {
// Open SSH agent socket
if err := os.RemoveAll(sshAuthSock); err != nil {
log.Fatal(err)
}
l, err := net.Listen("unix", sshAuthSock)
if err != nil {
log.Fatal(err)
}
defer l.Close()
// Accept new connections, dispatching them to an ssh agent server in the background
for {
conn, err := l.Accept()
if err != nil {
log.Fatal("accept error:", err)
}
go agent.ServeAgent(sshAgent, conn)
}
}()
return sshAuthSock, err
}
const letterBytes = "abcdefghijklmnopqrstuvwxyz"
func generateRandomString(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}
// ParsePrivateSSHKey parses a private key
func ParsePrivateSSHKey(privateKeyBytes []byte, passphrase string) (interface{}, error) {
var err error
var privateKey interface{}
if strings.Contains(string(privateKeyBytes), "ENCRYPTED") {
privateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKeyBytes, []byte(passphrase))
if err != nil {
return nil, err
}
} else {
privateKey, err = ssh.ParseRawPrivateKey(privateKeyBytes)
if err != nil {
return nil, err
}
}
return privateKey, nil
}