aboutsummaryrefslogtreecommitdiffstats
path: root/clients/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'clients/ssh')
-rw-r--r--clients/ssh/auth_method.go10
-rw-r--r--clients/ssh/git_upload_pack.go96
-rw-r--r--clients/ssh/git_upload_pack_test.go4
3 files changed, 60 insertions, 50 deletions
diff --git a/clients/ssh/auth_method.go b/clients/ssh/auth_method.go
index e55283e..1ce45ef 100644
--- a/clients/ssh/auth_method.go
+++ b/clients/ssh/auth_method.go
@@ -138,16 +138,22 @@ func (a *PublicKeysCallback) clientConfig() *ssh.ClientConfig {
}
}
+const DefaultSSHUsername = "git"
+
// Opens a pipe with the ssh agent and uses the pipe
// as the implementer of the public key callback function.
-func NewSSHAgentAuth() (*PublicKeysCallback, error) {
+func NewSSHAgentAuth(user string) (*PublicKeysCallback, error) {
+ if user == "" {
+ user = DefaultSSHUsername
+ }
+
pipe, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
if err != nil {
return nil, err
}
return &PublicKeysCallback{
- User: "git",
+ User: user,
Callback: agent.NewClient(pipe).Signers,
}, nil
}
diff --git a/clients/ssh/git_upload_pack.go b/clients/ssh/git_upload_pack.go
index eb5926e..d83aadb 100644
--- a/clients/ssh/git_upload_pack.go
+++ b/clients/ssh/git_upload_pack.go
@@ -1,6 +1,4 @@
// Package ssh implements a ssh client for go-git.
-//
-// The Connect() method is not allowed in ssh, use ConnectWithAuth() instead.
package ssh
import (
@@ -10,13 +8,12 @@ import (
"fmt"
"io"
"io/ioutil"
- "net/url"
+ "strings"
"gopkg.in/src-d/go-git.v4/clients/common"
"gopkg.in/src-d/go-git.v4/formats/pktline"
"golang.org/x/crypto/ssh"
- "gopkg.in/sourcegraph/go-vcsurl.v1"
)
// New errors introduced by this package.
@@ -32,79 +29,79 @@ var (
// GitUploadPackService holds the service information.
// The zero value is safe to use.
-// TODO: remove NewGitUploadPackService().
type GitUploadPackService struct {
connected bool
endpoint common.Endpoint
- vcs *vcsurl.RepoInfo
client *ssh.Client
auth AuthMethod
}
-// NewGitUploadPackService initialises a GitUploadPackService.
+// NewGitUploadPackService initialises a GitUploadPackService,
func NewGitUploadPackService(endpoint common.Endpoint) common.GitUploadPackService {
return &GitUploadPackService{endpoint: endpoint}
}
-// Connect cannot be used with SSH clients and always return
-// ErrAuthRequired. Use ConnectWithAuth instead.
+// Connect connects to the SSH server, unless a AuthMethod was set with SetAuth
+// method, by default uses an auth method based on PublicKeysCallback, it
+// connects to a SSH agent, using the address stored in the SSH_AUTH_SOCK
+// environment var
func (s *GitUploadPackService) Connect() error {
- auth, err := NewSSHAgentAuth()
- if err != nil {
- return err
- }
-
- return s.ConnectWithAuth(auth)
-}
-
-// ConnectWithAuth connects to ep using SSH. Authentication is handled
-// by auth.
-func (s *GitUploadPackService) ConnectWithAuth(auth common.AuthMethod) (err error) {
if s.connected {
return ErrAlreadyConnected
}
- s.vcs, err = vcsurl.Parse(s.endpoint.String())
- if err != nil {
+ if err := s.setAuthFromEndpoint(); err != nil {
return err
}
- url, err := vcsToURL(s.vcs)
+ var err error
+ s.client, err = ssh.Dial("tcp", s.getHostWithPort(), s.auth.clientConfig())
if err != nil {
- return
+ return err
}
- var ok bool
- s.auth, ok = auth.(AuthMethod)
- if !ok {
- return ErrInvalidAuthMethod
+ s.connected = true
+ return nil
+}
+
+func (s *GitUploadPackService) getHostWithPort() string {
+ host := s.endpoint.Host
+ if strings.Index(s.endpoint.Host, ":") == -1 {
+ host += ":22"
}
- s.client, err = ssh.Dial("tcp", url.Host, s.auth.clientConfig())
+ return host
+}
+
+func (s *GitUploadPackService) setAuthFromEndpoint() error {
+ var u string
+ if info := s.endpoint.User; info != nil {
+ u = info.Username()
+ }
+
+ var err error
+ s.auth, err = NewSSHAgentAuth(u)
if err != nil {
return err
}
- s.connected = true
- return
+ return nil
}
-func vcsToURL(vcs *vcsurl.RepoInfo) (u *url.URL, err error) {
- if vcs.VCS != vcsurl.Git {
- return nil, ErrUnsupportedVCS
- }
- if vcs.RepoHost != vcsurl.GitHub {
- return nil, ErrUnsupportedRepo
+// SetAuth sets the AuthMethod
+func (s *GitUploadPackService) SetAuth(auth common.AuthMethod) error {
+ var ok bool
+ s.auth, ok = auth.(AuthMethod)
+ if !ok {
+ return ErrInvalidAuthMethod
}
- s := "ssh://git@" + string(vcs.RepoHost) + ":22/" + vcs.FullName
- u, err = url.Parse(s)
- return
+
+ return nil
}
-// Info returns the GitUploadPackInfo of the repository.
-// The client must be connected with the repository (using
-// the ConnectWithAuth() method) before using this
-// method.
+// Info returns the GitUploadPackInfo of the repository. The client must be
+// connected with the repository (using the ConnectWithAuth() method) before
+// using this method.
func (s *GitUploadPackService) Info() (i *common.GitUploadPackInfo, err error) {
if !s.connected {
return nil, ErrNotConnected
@@ -120,7 +117,7 @@ func (s *GitUploadPackService) Info() (i *common.GitUploadPackInfo, err error) {
_ = session.Close()
}()
- out, err := session.Output("git-upload-pack " + s.vcs.FullName + ".git")
+ out, err := session.Output(s.getCommand())
if err != nil {
return nil, err
}
@@ -169,7 +166,7 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.Read
return nil, err
}
- if err := session.Start("git-upload-pack " + s.vcs.FullName + ".git"); err != nil {
+ if err := session.Start(s.getCommand()); err != nil {
return nil, err
}
@@ -209,3 +206,10 @@ func (s *GitUploadPackService) Fetch(r *common.GitUploadPackRequest) (rc io.Read
buf := bytes.NewBuffer(data)
return ioutil.NopCloser(buf), nil
}
+
+func (s *GitUploadPackService) getCommand() string {
+ directory := s.endpoint.Path
+ directory = directory[1:len(directory)]
+
+ return fmt.Sprintf("git-upload-pack %s", directory)
+}
diff --git a/clients/ssh/git_upload_pack_test.go b/clients/ssh/git_upload_pack_test.go
index b26276d..0785af5 100644
--- a/clients/ssh/git_upload_pack_test.go
+++ b/clients/ssh/git_upload_pack_test.go
@@ -32,9 +32,9 @@ type mockAuth struct{}
func (*mockAuth) Name() string { return "" }
func (*mockAuth) String() string { return "" }
-func (s *RemoteSuite) TestConnectWithAuthWrongType(c *C) {
+func (s *RemoteSuite) TestSetAuthWrongType(c *C) {
r := NewGitUploadPackService(s.Endpoint)
- c.Assert(r.ConnectWithAuth(&mockAuth{}), Equals, ErrInvalidAuthMethod)
+ c.Assert(r.SetAuth(&mockAuth{}), Equals, ErrInvalidAuthMethod)
}
func (s *RemoteSuite) TestAlreadyConnected(c *C) {