1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
package test
import (
"context"
"fmt"
"log"
"net"
"os"
"path/filepath"
"sync/atomic"
"testing"
"github.com/armon/go-socks5"
"github.com/gliderlabs/ssh"
"github.com/go-git/go-git/v5/plumbing/transport"
ggssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
fixtures "github.com/go-git/go-git-fixtures/v4"
stdssh "golang.org/x/crypto/ssh"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
type ProxyEnvSuite struct {
fixtures.Suite
port int
base string
}
var _ = Suite(&ProxyEnvSuite{})
var socksProxiedRequests int32
// This test tests proxy support via an env var, i.e. `ALL_PROXY`.
// Its located in a separate package because golang caches the value
// of proxy env vars leading to misleading/unexpected test results.
func (s *ProxyEnvSuite) TestCommand(c *C) {
socksListener, err := net.Listen("tcp", "127.0.0.1:0")
c.Assert(err, IsNil)
socksServer, err := socks5.New(&socks5.Config{
Rules: TestProxyRule{},
})
c.Assert(err, IsNil)
go func() {
socksServer.Serve(socksListener)
}()
socksProxyAddr := fmt.Sprintf("socks5://127.0.0.1:%d", socksListener.Addr().(*net.TCPAddr).Port)
os.Setenv("ALL_PROXY", socksProxyAddr)
defer os.Unsetenv("ALL_PROXY")
sshListener, err := net.Listen("tcp", "127.0.0.1:0")
c.Assert(err, IsNil)
sshServer := &ssh.Server{Handler: HandlerSSH}
go func() {
log.Fatal(sshServer.Serve(sshListener))
}()
s.port = sshListener.Addr().(*net.TCPAddr).Port
s.base, err = os.MkdirTemp(c.MkDir(), fmt.Sprintf("go-git-ssh-%d", s.port))
c.Assert(err, IsNil)
ggssh.DefaultAuthBuilder = func(user string) (ggssh.AuthMethod, error) {
return &ggssh.Password{User: user}, nil
}
ep := s.prepareRepository(c, fixtures.Basic().One(), "basic.git")
c.Assert(err, IsNil)
client := ggssh.NewClient(&stdssh.ClientConfig{
HostKeyCallback: stdssh.InsecureIgnoreHostKey(),
})
r, err := client.NewUploadPackSession(ep, nil)
c.Assert(err, IsNil)
defer func() { c.Assert(r.Close(), IsNil) }()
info, err := r.AdvertisedReferences()
c.Assert(err, IsNil)
c.Assert(info, NotNil)
proxyUsed := atomic.LoadInt32(&socksProxiedRequests) > 0
c.Assert(proxyUsed, Equals, true)
}
func (s *ProxyEnvSuite) prepareRepository(c *C, f *fixtures.Fixture, name string) *transport.Endpoint {
fs := f.DotGit()
err := fixtures.EnsureIsBare(fs)
c.Assert(err, IsNil)
path := filepath.Join(s.base, name)
err = os.Rename(fs.Root(), path)
c.Assert(err, IsNil)
return s.newEndpoint(c, name)
}
func (s *ProxyEnvSuite) newEndpoint(c *C, name string) *transport.Endpoint {
ep, err := transport.NewEndpoint(fmt.Sprintf(
"ssh://git@127.0.0.1:%d/%s/%s", s.port, filepath.ToSlash(s.base), name,
))
c.Assert(err, IsNil)
return ep
}
type TestProxyRule struct{}
func (dr TestProxyRule) Allow(ctx context.Context, req *socks5.Request) (context.Context, bool) {
atomic.AddInt32(&socksProxiedRequests, 1)
return ctx, true
}
|