diff options
-rw-r--r-- | .travis.yml | 16 | ||||
-rwxr-xr-x[-rw-r--r--] | .travis/install_key.sh | 12 | ||||
-rw-r--r-- | plumbing/format/packfile/decoder.go | 4 | ||||
-rw-r--r-- | plumbing/format/packfile/scanner.go | 5 | ||||
-rw-r--r-- | plumbing/format/packfile/scanner_test.go | 5 | ||||
-rw-r--r-- | plumbing/format/pktline/scanner_test.go | 2 | ||||
-rw-r--r-- | plumbing/object/change_adaptor.go | 9 | ||||
-rw-r--r-- | plumbing/object/change_test.go | 5 | ||||
-rw-r--r-- | plumbing/transport/ssh/auth_method.go | 33 | ||||
-rw-r--r-- | plumbing/transport/ssh/auth_method_test.go | 11 | ||||
-rw-r--r-- | plumbing/transport/ssh/common.go | 8 | ||||
-rw-r--r-- | plumbing/transport/ssh/upload_pack_test.go | 19 | ||||
-rw-r--r-- | remote.go | 2 | ||||
-rw-r--r-- | utils/merkletrie/difftree_test.go | 2 | ||||
-rw-r--r-- | utils/merkletrie/internal/fsnoder/new.go | 2 | ||||
-rw-r--r-- | utils/merkletrie/iter_test.go | 6 |
16 files changed, 97 insertions, 44 deletions
diff --git a/.travis.yml b/.travis.yml index e527225..c81b17e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,15 +25,18 @@ before_script: - make build-git before_install: - - eval "$(ssh-agent -s)" - # we only decrypt the SSH key when we aren't in a pull request - #- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash .travis/install_key.sh; fi' - #- 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export SSH_AUTH_SOCK="" ; fi'\ - # temporal fix skip of SSH test - - export SSH_AUTH_SOCK="" - git config --global user.email "travis@example.com" - git config --global user.name "Travis CI" + # we only decrypt the SSH key when we aren't in a pull request + - > + if [ "$TRAVIS_PULL_REQUEST" = "false" ] ; then \ + bash .travis/install_key.sh; \ + export SSH_TEST_PRIVATE_KEY=$HOME/.travis/deploy.pem; \ + else \ + export SSH_AUTH_SOCK=""; \ + fi + install: - go get -v -t ./... @@ -42,6 +45,7 @@ script: - export PATH=$GIT_DIST_PATH:$PATH - git version - make test-coverage + - go vet ./... after_success: - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file diff --git a/.travis/install_key.sh b/.travis/install_key.sh index b035092..95a6571 100644..100755 --- a/.travis/install_key.sh +++ b/.travis/install_key.sh @@ -1,3 +1,9 @@ -openssl aes-256-cbc -K $encrypted_1477e58fe67a_key -iv $encrypted_1477e58fe67a_iv -in .travis/deploy.pem.enc -out .travis/deploy.pem -d -chmod 600 .travis/deploy.pem -ssh-add .travis/deploy.pem +#!/bin/bash +openssl aes-256-cbc \ + -K $encrypted_1477e58fe67a_key \ + -iv $encrypted_1477e58fe67a_iv \ + -in .travis/deploy.pem.enc \ + -out $HOME/.travis/deploy.pem -d + +chmod 600 $HOME/.travis/deploy.pem + diff --git a/plumbing/format/packfile/decoder.go b/plumbing/format/packfile/decoder.go index f3328ef..21ddbbf 100644 --- a/plumbing/format/packfile/decoder.go +++ b/plumbing/format/packfile/decoder.go @@ -310,13 +310,13 @@ func (d *Decoder) DecodeObjectAt(offset int64) (plumbing.EncodedObject, error) { return nil, ErrNonSeekable } - beforeJump, err := d.s.Seek(offset) + beforeJump, err := d.s.SeekFromStart(offset) if err != nil { return nil, err } defer func() { - _, seekErr := d.s.Seek(beforeJump) + _, seekErr := d.s.SeekFromStart(beforeJump) if err == nil { err = seekErr } diff --git a/plumbing/format/packfile/scanner.go b/plumbing/format/packfile/scanner.go index d8cece6..97512d1 100644 --- a/plumbing/format/packfile/scanner.go +++ b/plumbing/format/packfile/scanner.go @@ -300,8 +300,9 @@ func (s *Scanner) copyObject(w io.Writer) (int64, error) { return io.Copy(w, s.zr) } -// Seek sets a new offset from start, returns the old position before the change -func (s *Scanner) Seek(offset int64) (previous int64, err error) { +// SeekFromStart sets a new offset from start, returns the old position before +// the change. +func (s *Scanner) SeekFromStart(offset int64) (previous int64, err error) { // if seeking we assume that you are not interested on the header if s.version == 0 { s.version = VersionSupported diff --git a/plumbing/format/packfile/scanner_test.go b/plumbing/format/packfile/scanner_test.go index f2aa5fb..1ca8b6e 100644 --- a/plumbing/format/packfile/scanner_test.go +++ b/plumbing/format/packfile/scanner_test.go @@ -4,9 +4,10 @@ import ( "bytes" "io" - . "gopkg.in/check.v1" - "github.com/src-d/go-git-fixtures" "gopkg.in/src-d/go-git.v4/plumbing" + + "github.com/src-d/go-git-fixtures" + . "gopkg.in/check.v1" ) type ScannerSuite struct { diff --git a/plumbing/format/pktline/scanner_test.go b/plumbing/format/pktline/scanner_test.go index b8a78ec..048ea38 100644 --- a/plumbing/format/pktline/scanner_test.go +++ b/plumbing/format/pktline/scanner_test.go @@ -218,7 +218,7 @@ func ExampleScanner() { for s.Scan() { payload := s.Bytes() if len(payload) == 0 { // zero sized payloads correspond to flush-pkts. - fmt.Println("FLUSH-PKT DETECTED\n") + fmt.Println("FLUSH-PKT DETECTED") } else { // otherwise, you will be able to access the full payload. fmt.Printf("PAYLOAD = %q\n", string(payload)) } diff --git a/plumbing/object/change_adaptor.go b/plumbing/object/change_adaptor.go index cf8de6c..49b6545 100644 --- a/plumbing/object/change_adaptor.go +++ b/plumbing/object/change_adaptor.go @@ -1,6 +1,7 @@ package object import ( + "errors" "fmt" "gopkg.in/src-d/go-git.v4/utils/merkletrie" @@ -15,11 +16,11 @@ func newChange(c merkletrie.Change) (*Change, error) { var err error if ret.From, err = newChangeEntry(c.From); err != nil { - return nil, fmt.Errorf("From field: ", err) + return nil, fmt.Errorf("From field: %s", err) } if ret.To, err = newChangeEntry(c.To); err != nil { - return nil, fmt.Errorf("To field: ", err) + return nil, fmt.Errorf("To field: %s", err) } return ret, nil @@ -32,7 +33,7 @@ func newChangeEntry(p noder.Path) (ChangeEntry, error) { asTreeNoder, ok := p.Last().(*treeNoder) if !ok { - return ChangeEntry{}, fmt.Errorf("cannot transform non-TreeNoders") + return ChangeEntry{}, errors.New("cannot transform non-TreeNoders") } return ChangeEntry{ @@ -52,7 +53,7 @@ func newChanges(src merkletrie.Changes) (Changes, error) { for i, e := range src { ret[i], err = newChange(e) if err != nil { - return nil, fmt.Errorf("change #%d: %s", err) + return nil, fmt.Errorf("change #%d: %s", i, err) } } diff --git a/plumbing/object/change_test.go b/plumbing/object/change_test.go index 005ceb0..bfd4613 100644 --- a/plumbing/object/change_test.go +++ b/plumbing/object/change_test.go @@ -236,10 +236,7 @@ func (s *ChangeSuite) TestNoFileFilemodes(c *C) { c.Assert(err, IsNil) for _, change := range changes { _, _, err := change.Files() - if err != nil { - panic(err) - c.Assert(err, IsNil) - } + c.Assert(err, IsNil) } prev = commit diff --git a/plumbing/transport/ssh/auth_method.go b/plumbing/transport/ssh/auth_method.go index ad92ee1..a3e1ad1 100644 --- a/plumbing/transport/ssh/auth_method.go +++ b/plumbing/transport/ssh/auth_method.go @@ -1,6 +1,8 @@ package ssh import ( + "crypto/x509" + "encoding/pem" "errors" "fmt" "io/ioutil" @@ -9,9 +11,11 @@ import ( "os/user" "path/filepath" - "github.com/src-d/crypto/ssh/knownhosts" + "gopkg.in/src-d/go-git.v4/plumbing/transport" + "golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh/agent" + "golang.org/x/crypto/ssh/knownhosts" ) const DefaultUsername = "git" @@ -22,6 +26,7 @@ var ErrEmptySSHAgentAddr = errors.New("SSH_AUTH_SOCK env variable is required") // must implement. The clientConfig method returns the ssh client // configuration needed to establish an ssh connection. type AuthMethod interface { + transport.AuthMethod clientConfig() *ssh.ClientConfig hostKeyCallback() (ssh.HostKeyCallback, error) } @@ -112,9 +117,22 @@ type PublicKeys struct { baseAuthMethod } -// NewPublicKeys returns a PublicKeys from a PEM encoded private key. It -// supports RSA (PKCS#1), DSA (OpenSSL), and ECDSA private keys. -func NewPublicKeys(user string, pemBytes []byte) (AuthMethod, error) { +// NewPublicKeys returns a PublicKeys from a PEM encoded private key. An +// encryption password should be given if the pemBytes contains a password +// encrypted PEM block otherwise password should be empty. It supports RSA +// (PKCS#1), DSA (OpenSSL), and ECDSA private keys. +func NewPublicKeys(user string, pemBytes []byte, password string) (AuthMethod, error) { + block, _ := pem.Decode(pemBytes) + if x509.IsEncryptedPEMBlock(block) { + key, err := x509.DecryptPEMBlock(block, []byte(password)) + if err != nil { + return nil, err + } + + block = &pem.Block{Type: block.Type, Bytes: key} + pemBytes = pem.EncodeToMemory(block) + } + signer, err := ssh.ParsePrivateKey(pemBytes) if err != nil { return nil, err @@ -124,14 +142,15 @@ func NewPublicKeys(user string, pemBytes []byte) (AuthMethod, error) { } // NewPublicKeysFromFile returns a PublicKeys from a file containing a PEM -// encoded private key. -func NewPublicKeysFromFile(user string, pemFile string) (AuthMethod, error) { +// encoded private key. An encryption password should be given if the pemBytes +// contains a password encrypted PEM block otherwise password should be empty. +func NewPublicKeysFromFile(user, pemFile, password string) (AuthMethod, error) { bytes, err := ioutil.ReadFile(pemFile) if err != nil { return nil, err } - return NewPublicKeys(user, bytes) + return NewPublicKeys(user, bytes, password) } func (a *PublicKeys) Name() string { diff --git a/plumbing/transport/ssh/auth_method_test.go b/plumbing/transport/ssh/auth_method_test.go index 43b34df..6f3d82f 100644 --- a/plumbing/transport/ssh/auth_method_test.go +++ b/plumbing/transport/ssh/auth_method_test.go @@ -109,7 +109,14 @@ func (s *SuiteCommon) TestNewSSHAgentAuth(c *C) { } func (*SuiteCommon) TestNewPublicKeys(c *C) { - auth, err := NewPublicKeys("foo", testdata.PEMBytes["rsa"]) + auth, err := NewPublicKeys("foo", testdata.PEMBytes["rsa"], "") + c.Assert(err, IsNil) + c.Assert(auth, NotNil) +} + +func (*SuiteCommon) TestNewPublicKeysWithEncryptedPEM(c *C) { + f := testdata.PEMEncryptedKeys[0] + auth, err := NewPublicKeys("foo", f.PEMBytes, f.EncryptionKey) c.Assert(err, IsNil) c.Assert(auth, NotNil) } @@ -122,7 +129,7 @@ func (*SuiteCommon) TestNewPublicKeysFromFile(c *C) { c.Assert(f.Close(), IsNil) defer os.RemoveAll(f.Name()) - auth, err := NewPublicKeysFromFile("foo", f.Name()) + auth, err := NewPublicKeysFromFile("foo", f.Name(), "") c.Assert(err, IsNil) c.Assert(auth, NotNil) } diff --git a/plumbing/transport/ssh/common.go b/plumbing/transport/ssh/common.go index 9b484f9..7b44a91 100644 --- a/plumbing/transport/ssh/common.go +++ b/plumbing/transport/ssh/common.go @@ -14,6 +14,12 @@ import ( // DefaultClient is the default SSH client. var DefaultClient = common.NewClient(&runner{}) +// DefaultAuthBuilder is the function used to create a default AuthMethod, when +// the user doesn't provide any. +var DefaultAuthBuilder = func(user string) (AuthMethod, error) { + return NewSSHAgentAuth(user) +} + type runner struct{} func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod) (common.Command, error) { @@ -119,7 +125,7 @@ func (c *command) setAuthFromEndpoint() error { } var err error - c.auth, err = NewSSHAgentAuth(u) + c.auth, err = DefaultAuthBuilder(u) return err } diff --git a/plumbing/transport/ssh/upload_pack_test.go b/plumbing/transport/ssh/upload_pack_test.go index 54d523a..cb9baa5 100644 --- a/plumbing/transport/ssh/upload_pack_test.go +++ b/plumbing/transport/ssh/upload_pack_test.go @@ -16,10 +16,7 @@ type UploadPackSuite struct { var _ = Suite(&UploadPackSuite{}) func (s *UploadPackSuite) SetUpSuite(c *C) { - if os.Getenv("SSH_AUTH_SOCK") == "" { - c.Skip("SSH_AUTH_SOCK is not set") - } - + s.setAuthBuilder(c) s.UploadPackSuite.Client = DefaultClient ep, err := transport.NewEndpoint("git@github.com:git-fixtures/basic.git") @@ -34,3 +31,17 @@ func (s *UploadPackSuite) SetUpSuite(c *C) { c.Assert(err, IsNil) s.UploadPackSuite.NonExistentEndpoint = ep } + +func (s *UploadPackSuite) setAuthBuilder(c *C) { + privateKey := os.Getenv("SSH_TEST_PRIVATE_KEY") + if privateKey != "" { + DefaultAuthBuilder = func(user string) (AuthMethod, error) { + return NewPublicKeysFromFile(user, privateKey, "") + } + } + + if privateKey == "" && os.Getenv("SSH_AUTH_SOCK") == "" { + c.Skip("SSH_AUTH_SOCK or SSH_TEST_PRIVATE_KEY are required") + return + } +} @@ -41,7 +41,7 @@ func (r *Remote) String() string { fetch := r.c.URL push := r.c.URL - return fmt.Sprintf("%s\t%s (fetch)\n%[1]s\t%s (push)", r.c.Name, fetch, push) + return fmt.Sprintf("%s\t%s (fetch)\n%[1]s\t%[3]s (push)", r.c.Name, fetch, push) } // Fetch fetches references from the remote to the local repository. diff --git a/utils/merkletrie/difftree_test.go b/utils/merkletrie/difftree_test.go index dd5b11d..9f033b1 100644 --- a/utils/merkletrie/difftree_test.go +++ b/utils/merkletrie/difftree_test.go @@ -120,7 +120,7 @@ func newChanges(original merkletrie.Changes) (changes, error) { path: c.From.String(), } default: - panic(fmt.Sprintf("unsupported action %d", c.Action)) + panic(fmt.Sprintf("unsupported action %d", action)) } } diff --git a/utils/merkletrie/internal/fsnoder/new.go b/utils/merkletrie/internal/fsnoder/new.go index 1e33020..ab749fd 100644 --- a/utils/merkletrie/internal/fsnoder/new.go +++ b/utils/merkletrie/internal/fsnoder/new.go @@ -34,7 +34,7 @@ func decodeDir(data []byte, isRoot bool) (*dir, error) { var name string switch end := bytes.IndexRune(data, dirStartMark); end { case -1: - return nil, fmt.Errorf("%c not found") + return nil, fmt.Errorf("%c not found", dirStartMark) case 0: if isRoot { name = "" diff --git a/utils/merkletrie/iter_test.go b/utils/merkletrie/iter_test.go index ba28f0b..7e8c302 100644 --- a/utils/merkletrie/iter_test.go +++ b/utils/merkletrie/iter_test.go @@ -65,7 +65,7 @@ func (t test) run(c *C, iter *merkletrie.Iter, var obtained noder.Path var err error - for i := range t.operations { + for i, b := range t.operations { comment := Commentf("\ntree: %q\ntest #%d (%q)\noperation #%d (%q)", treeDescription, testNumber, t.operations, i, t.operations[i]) @@ -81,8 +81,8 @@ func (t test) run(c *C, iter *merkletrie.Iter, c.Assert(err, IsNil) } default: - c.Fatalf("unknown operation at test %d, operation %d (%s)\n", - testNumber, i, t.operations[i]) + c.Fatalf("unknown operation at test %d, operation %d (%c)\n", + testNumber, i, b) } if i >= len(expectedChunks) { c.Assert(err, Equals, io.EOF, comment) |