diff options
Diffstat (limited to 'clients/ssh')
-rw-r--r-- | clients/ssh/auth_method.go | 10 | ||||
-rw-r--r-- | clients/ssh/git_upload_pack.go | 96 | ||||
-rw-r--r-- | clients/ssh/git_upload_pack_test.go | 4 |
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) { |