Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit d324899

Browse files
authored
Merge pull request #347 from mcuadros/ssh
transport: ssh, NewPublicKeys helper
2 parents a41491f + 373e597 commit d324899

File tree

2 files changed

+68
-23
lines changed

2 files changed

+68
-23
lines changed

plumbing/transport/ssh/auth_method.go

+46-23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package ssh
33
import (
44
"errors"
55
"fmt"
6+
"io/ioutil"
67
"net"
78
"os"
89
"os/user"
@@ -13,6 +14,8 @@ import (
1314
"golang.org/x/crypto/ssh/agent"
1415
)
1516

17+
const DefaultUsername = "git"
18+
1619
var ErrEmptySSHAgentAddr = errors.New("SSH_AUTH_SOCK env variable is required")
1720

1821
// AuthMethod is the interface all auth methods for the ssh client
@@ -102,14 +105,35 @@ func (a *PasswordCallback) clientConfig() *ssh.ClientConfig {
102105
}
103106
}
104107

105-
// PublicKeys implements AuthMethod by using the given
106-
// key pairs.
108+
// PublicKeys implements AuthMethod by using the given key pairs.
107109
type PublicKeys struct {
108110
User string
109111
Signer ssh.Signer
110112
baseAuthMethod
111113
}
112114

115+
// NewPublicKeys returns a PublicKeys from a PEM encoded private key. It
116+
// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys.
117+
func NewPublicKeys(user string, pemBytes []byte) (AuthMethod, error) {
118+
signer, err := ssh.ParsePrivateKey(pemBytes)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
return &PublicKeys{User: user, Signer: signer}, nil
124+
}
125+
126+
// NewPublicKeysFromFile returns a PublicKeys from a file containing a PEM
127+
// encoded private key.
128+
func NewPublicKeysFromFile(user string, pemFile string) (AuthMethod, error) {
129+
bytes, err := ioutil.ReadFile(pemFile)
130+
if err != nil {
131+
return nil, err
132+
}
133+
134+
return NewPublicKeys(user, bytes)
135+
}
136+
113137
func (a *PublicKeys) Name() string {
114138
return PublicKeysName
115139
}
@@ -133,28 +157,12 @@ type PublicKeysCallback struct {
133157
baseAuthMethod
134158
}
135159

136-
func (a *PublicKeysCallback) Name() string {
137-
return PublicKeysCallbackName
138-
}
139-
140-
func (a *PublicKeysCallback) String() string {
141-
return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
142-
}
143-
144-
func (a *PublicKeysCallback) clientConfig() *ssh.ClientConfig {
145-
return &ssh.ClientConfig{
146-
User: a.User,
147-
Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)},
148-
}
149-
}
150-
151-
const DefaultSSHUsername = "git"
152-
153-
// NewSSHAgentAuth opens a pipe with the SSH agent and uses the pipe
154-
// as the implementer of the public key callback function.
155-
func NewSSHAgentAuth(user string) (*PublicKeysCallback, error) {
160+
// NewSSHAgentAuth returns a PublicKeysCallback based on a SSH agent, it opens
161+
// a pipe with the SSH agent and uses the pipe as the implementer of the public
162+
// key callback function.
163+
func NewSSHAgentAuth(user string) (AuthMethod, error) {
156164
if user == "" {
157-
user = DefaultSSHUsername
165+
user = DefaultUsername
158166
}
159167

160168
sshAgentAddr := os.Getenv("SSH_AUTH_SOCK")
@@ -173,6 +181,21 @@ func NewSSHAgentAuth(user string) (*PublicKeysCallback, error) {
173181
}, nil
174182
}
175183

184+
func (a *PublicKeysCallback) Name() string {
185+
return PublicKeysCallbackName
186+
}
187+
188+
func (a *PublicKeysCallback) String() string {
189+
return fmt.Sprintf("user: %s, name: %s", a.User, a.Name())
190+
}
191+
192+
func (a *PublicKeysCallback) clientConfig() *ssh.ClientConfig {
193+
return &ssh.ClientConfig{
194+
User: a.User,
195+
Auth: []ssh.AuthMethod{ssh.PublicKeysCallback(a.Callback)},
196+
}
197+
}
198+
176199
// NewKnownHostsCallback returns ssh.HostKeyCallback based on a file based on a
177200
// know_hosts file. http://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT
178201
//

plumbing/transport/ssh/auth_method_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package ssh
22

33
import (
44
"fmt"
5+
"io/ioutil"
56
"os"
67

8+
"golang.org/x/crypto/ssh/testdata"
9+
710
. "gopkg.in/check.v1"
811
)
912

@@ -104,3 +107,22 @@ func (s *SuiteCommon) TestNewSSHAgentAuth(c *C) {
104107
c.Assert(k, IsNil)
105108
c.Assert(err, Equals, ErrEmptySSHAgentAddr)
106109
}
110+
111+
func (*SuiteCommon) TestNewPublicKeys(c *C) {
112+
auth, err := NewPublicKeys("foo", testdata.PEMBytes["rsa"])
113+
c.Assert(err, IsNil)
114+
c.Assert(auth, NotNil)
115+
}
116+
117+
func (*SuiteCommon) TestNewPublicKeysFromFile(c *C) {
118+
f, err := ioutil.TempFile("", "ssh-test")
119+
c.Assert(err, IsNil)
120+
_, err = f.Write(testdata.PEMBytes["rsa"])
121+
c.Assert(err, IsNil)
122+
c.Assert(f.Close(), IsNil)
123+
defer os.RemoveAll(f.Name())
124+
125+
auth, err := NewPublicKeysFromFile("foo", f.Name())
126+
c.Assert(err, IsNil)
127+
c.Assert(auth, NotNil)
128+
}

0 commit comments

Comments
 (0)