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

Commit 264d094

Browse files
committed
plumbing: transport ssh, ssh_config implementation
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
1 parent 479d38b commit 264d094

File tree

2 files changed

+107
-12
lines changed

2 files changed

+107
-12
lines changed

plumbing/transport/ssh/common.go

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ import (
99
"gopkg.in/src-d/go-git.v4/plumbing/transport"
1010
"gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common"
1111

12-
"golang.org/x/crypto/ssh"
1312
"github.com/kevinburke/ssh_config"
13+
"golang.org/x/crypto/ssh"
1414
)
1515

1616
// DefaultClient is the default SSH client.
1717
var DefaultClient = NewClient(nil)
1818

19+
// DefaultSSHConfig is the reader used to access parameters stored in the
20+
// system's ssh_config files. If nil all the ssh_config are ignored.
21+
var DefaultSSHConfig sshConfig = ssh_config.DefaultUserSettings
22+
23+
type sshConfig interface {
24+
Get(alias, key string) string
25+
}
26+
1927
// NewClient creates a new SSH client with an optional *ssh.ClientConfig.
2028
func NewClient(config *ssh.ClientConfig) transport.Transport {
2129
return common.NewClient(&runner{config: config})
@@ -123,26 +131,46 @@ func (c *command) connect() error {
123131
}
124132

125133
func (c *command) getHostWithPort() string {
134+
if addr, found := c.doGetHostWithPortFromSSHConfig(); found {
135+
return addr
136+
}
137+
126138
host := c.endpoint.Host
139+
port := c.endpoint.Port
140+
if port <= 0 {
141+
port = DefaultPort
142+
}
127143

128-
configHost := ssh_config.Get(host, "Hostname")
129-
if (configHost != "") {
130-
host = configHost
144+
return fmt.Sprintf("%s:%d", host, port)
145+
}
146+
147+
func (c *command) doGetHostWithPortFromSSHConfig() (addr string, found bool) {
148+
if DefaultSSHConfig == nil {
149+
return
131150
}
132151

152+
host := c.endpoint.Host
133153
port := c.endpoint.Port
134-
configPort := ssh_config.Get(host, "Port")
135-
if (configPort != "") {
136-
i, err := strconv.Atoi(configPort)
137-
if err != nil {
154+
155+
configHost := DefaultSSHConfig.Get(c.endpoint.Host, "Hostname")
156+
if configHost != "" {
157+
host = configHost
158+
found = true
159+
}
160+
161+
if !found {
162+
return
163+
}
164+
165+
configPort := DefaultSSHConfig.Get(c.endpoint.Host, "Port")
166+
if configPort != "" {
167+
if i, err := strconv.Atoi(configPort); err == nil {
138168
port = i
139169
}
140170
}
141-
if port <= 0 {
142-
port = DefaultPort
143-
}
144171

145-
return fmt.Sprintf("%s:%d", host, port)
172+
addr = fmt.Sprintf("%s:%d", host, port)
173+
return
146174
}
147175

148176
func (c *command) setAuthFromEndpoint() error {

plumbing/transport/ssh/common_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ package ssh
33
import (
44
"testing"
55

6+
"github.com/kevinburke/ssh_config"
7+
68
"golang.org/x/crypto/ssh"
79

810
. "gopkg.in/check.v1"
11+
"gopkg.in/src-d/go-git.v4/plumbing/transport"
912
)
1013

1114
func Test(t *testing.T) { TestingT(t) }
@@ -39,3 +42,67 @@ func (s *SuiteCommon) TestOverrideConfigKeep(c *C) {
3942
overrideConfig(config, target)
4043
c.Assert(target.User, Equals, "foo")
4144
}
45+
46+
func (s *SuiteCommon) TestDefaultSSHConfig(c *C) {
47+
defer func() {
48+
DefaultSSHConfig = ssh_config.DefaultUserSettings
49+
}()
50+
51+
DefaultSSHConfig = &mockSSHConfig{map[string]map[string]string{
52+
"github.com": map[string]string{
53+
"Hostname": "foo.local",
54+
"Port": "42",
55+
},
56+
}}
57+
58+
ep, err := transport.NewEndpoint("git@github.com:foo/bar.git")
59+
c.Assert(err, IsNil)
60+
61+
cmd := &command{endpoint: ep}
62+
c.Assert(cmd.getHostWithPort(), Equals, "foo.local:42")
63+
}
64+
65+
func (s *SuiteCommon) TestDefaultSSHConfigNil(c *C) {
66+
defer func() {
67+
DefaultSSHConfig = ssh_config.DefaultUserSettings
68+
}()
69+
70+
DefaultSSHConfig = nil
71+
72+
ep, err := transport.NewEndpoint("git@github.com:foo/bar.git")
73+
c.Assert(err, IsNil)
74+
75+
cmd := &command{endpoint: ep}
76+
c.Assert(cmd.getHostWithPort(), Equals, "github.com:22")
77+
}
78+
79+
func (s *SuiteCommon) TestDefaultSSHConfigWildcard(c *C) {
80+
defer func() {
81+
DefaultSSHConfig = ssh_config.DefaultUserSettings
82+
}()
83+
84+
DefaultSSHConfig = &mockSSHConfig{Values: map[string]map[string]string{
85+
"*": map[string]string{
86+
"Port": "42",
87+
},
88+
}}
89+
90+
ep, err := transport.NewEndpoint("git@github.com:foo/bar.git")
91+
c.Assert(err, IsNil)
92+
93+
cmd := &command{endpoint: ep}
94+
c.Assert(cmd.getHostWithPort(), Equals, "github.com:22")
95+
}
96+
97+
type mockSSHConfig struct {
98+
Values map[string]map[string]string
99+
}
100+
101+
func (c *mockSSHConfig) Get(alias, key string) string {
102+
a, ok := c.Values[alias]
103+
if !ok {
104+
return c.Values["*"][key]
105+
}
106+
107+
return a[key]
108+
}

0 commit comments

Comments
 (0)