diff options
author | Máximo Cuadros <mcuadros@gmail.com> | 2017-12-11 13:02:02 +0100 |
---|---|---|
committer | Máximo Cuadros <mcuadros@gmail.com> | 2017-12-11 13:02:02 +0100 |
commit | 264d094d8dce590d00fba1683cb7c74ff0c01a74 (patch) | |
tree | 302e69a5a63fb0e0dcb38c37952ccc6c996855fd | |
parent | 479d38ba02f553550c6cd2b7133a1a140a361080 (diff) | |
download | go-git-264d094d8dce590d00fba1683cb7c74ff0c01a74.tar.gz |
plumbing: transport ssh, ssh_config implementation
Signed-off-by: Máximo Cuadros <mcuadros@gmail.com>
-rw-r--r-- | plumbing/transport/ssh/common.go | 52 | ||||
-rw-r--r-- | plumbing/transport/ssh/common_test.go | 67 |
2 files changed, 107 insertions, 12 deletions
diff --git a/plumbing/transport/ssh/common.go b/plumbing/transport/ssh/common.go index 872379a..e4a3d18 100644 --- a/plumbing/transport/ssh/common.go +++ b/plumbing/transport/ssh/common.go @@ -9,13 +9,21 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/transport" "gopkg.in/src-d/go-git.v4/plumbing/transport/internal/common" - "golang.org/x/crypto/ssh" "github.com/kevinburke/ssh_config" + "golang.org/x/crypto/ssh" ) // DefaultClient is the default SSH client. var DefaultClient = NewClient(nil) +// DefaultSSHConfig is the reader used to access parameters stored in the +// system's ssh_config files. If nil all the ssh_config are ignored. +var DefaultSSHConfig sshConfig = ssh_config.DefaultUserSettings + +type sshConfig interface { + Get(alias, key string) string +} + // NewClient creates a new SSH client with an optional *ssh.ClientConfig. func NewClient(config *ssh.ClientConfig) transport.Transport { return common.NewClient(&runner{config: config}) @@ -123,26 +131,46 @@ func (c *command) connect() error { } func (c *command) getHostWithPort() string { + if addr, found := c.doGetHostWithPortFromSSHConfig(); found { + return addr + } + host := c.endpoint.Host + port := c.endpoint.Port + if port <= 0 { + port = DefaultPort + } - configHost := ssh_config.Get(host, "Hostname") - if (configHost != "") { - host = configHost + return fmt.Sprintf("%s:%d", host, port) +} + +func (c *command) doGetHostWithPortFromSSHConfig() (addr string, found bool) { + if DefaultSSHConfig == nil { + return } + host := c.endpoint.Host port := c.endpoint.Port - configPort := ssh_config.Get(host, "Port") - if (configPort != "") { - i, err := strconv.Atoi(configPort) - if err != nil { + + configHost := DefaultSSHConfig.Get(c.endpoint.Host, "Hostname") + if configHost != "" { + host = configHost + found = true + } + + if !found { + return + } + + configPort := DefaultSSHConfig.Get(c.endpoint.Host, "Port") + if configPort != "" { + if i, err := strconv.Atoi(configPort); err == nil { port = i } } - if port <= 0 { - port = DefaultPort - } - return fmt.Sprintf("%s:%d", host, port) + addr = fmt.Sprintf("%s:%d", host, port) + return } func (c *command) setAuthFromEndpoint() error { diff --git a/plumbing/transport/ssh/common_test.go b/plumbing/transport/ssh/common_test.go index 5315e28..faa0503 100644 --- a/plumbing/transport/ssh/common_test.go +++ b/plumbing/transport/ssh/common_test.go @@ -3,9 +3,12 @@ package ssh import ( "testing" + "github.com/kevinburke/ssh_config" + "golang.org/x/crypto/ssh" . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/plumbing/transport" ) func Test(t *testing.T) { TestingT(t) } @@ -39,3 +42,67 @@ func (s *SuiteCommon) TestOverrideConfigKeep(c *C) { overrideConfig(config, target) c.Assert(target.User, Equals, "foo") } + +func (s *SuiteCommon) TestDefaultSSHConfig(c *C) { + defer func() { + DefaultSSHConfig = ssh_config.DefaultUserSettings + }() + + DefaultSSHConfig = &mockSSHConfig{map[string]map[string]string{ + "github.com": map[string]string{ + "Hostname": "foo.local", + "Port": "42", + }, + }} + + ep, err := transport.NewEndpoint("git@github.com:foo/bar.git") + c.Assert(err, IsNil) + + cmd := &command{endpoint: ep} + c.Assert(cmd.getHostWithPort(), Equals, "foo.local:42") +} + +func (s *SuiteCommon) TestDefaultSSHConfigNil(c *C) { + defer func() { + DefaultSSHConfig = ssh_config.DefaultUserSettings + }() + + DefaultSSHConfig = nil + + ep, err := transport.NewEndpoint("git@github.com:foo/bar.git") + c.Assert(err, IsNil) + + cmd := &command{endpoint: ep} + c.Assert(cmd.getHostWithPort(), Equals, "github.com:22") +} + +func (s *SuiteCommon) TestDefaultSSHConfigWildcard(c *C) { + defer func() { + DefaultSSHConfig = ssh_config.DefaultUserSettings + }() + + DefaultSSHConfig = &mockSSHConfig{Values: map[string]map[string]string{ + "*": map[string]string{ + "Port": "42", + }, + }} + + ep, err := transport.NewEndpoint("git@github.com:foo/bar.git") + c.Assert(err, IsNil) + + cmd := &command{endpoint: ep} + c.Assert(cmd.getHostWithPort(), Equals, "github.com:22") +} + +type mockSSHConfig struct { + Values map[string]map[string]string +} + +func (c *mockSSHConfig) Get(alias, key string) string { + a, ok := c.Values[alias] + if !ok { + return c.Values["*"][key] + } + + return a[key] +} |