Imported Upstream version 2.4.2 upstream/2.4.2
authorhyokeun <hyokeun.jeon@samsung.com>
Fri, 21 Dec 2018 05:52:15 +0000 (14:52 +0900)
committerhyokeun <hyokeun.jeon@samsung.com>
Fri, 21 Dec 2018 05:52:15 +0000 (14:52 +0900)
22 files changed:
CHANGELOG.md
config/netrc.go
config/version.go
debian/changelog
glide.lock
glide.yaml
lfsapi/auth.go
lfsapi/client.go
lfsapi/client_test.go
lfsapi/netrc.go
lfsapi/netrc_test.go
lfsapi/ntlm.go
rpm/SPECS/git-lfs.spec
test/test-credentials.sh
vendor/github.com/git-lfs/go-netrc/.hgignore [moved from vendor/github.com/bgentry/go-netrc/.hgignore with 100% similarity]
vendor/github.com/git-lfs/go-netrc/LICENSE [moved from vendor/github.com/bgentry/go-netrc/LICENSE with 100% similarity]
vendor/github.com/git-lfs/go-netrc/README.md [moved from vendor/github.com/bgentry/go-netrc/README.md with 100% similarity]
vendor/github.com/git-lfs/go-netrc/netrc/examples/bad_default_order.netrc [moved from vendor/github.com/bgentry/go-netrc/netrc/examples/bad_default_order.netrc with 100% similarity]
vendor/github.com/git-lfs/go-netrc/netrc/examples/good.netrc [moved from vendor/github.com/bgentry/go-netrc/netrc/examples/good.netrc with 79% similarity]
vendor/github.com/git-lfs/go-netrc/netrc/netrc.go [moved from vendor/github.com/bgentry/go-netrc/netrc/netrc.go with 98% similarity]
vendor/github.com/git-lfs/go-netrc/netrc/netrc_test.go [moved from vendor/github.com/bgentry/go-netrc/netrc/netrc_test.go with 99% similarity]
versioninfo.json

index 902b598..0ba431c 100644 (file)
@@ -1,6 +1,13 @@
 # Git LFS Changelog
 
-### 2.4.1 (18 May, 2018)
+## 2.4.2 (28 May, 2018)
+
+### Bugs
+
+* lfsapi: re-authenticate HTTP redirects when needed #3028 (@ttaylorr)
+* lfsapi: allow unknown keywords in netrc file(s) #3027 (@ttaylorr)
+
+## 2.4.1 (18 May, 2018)
 
 This release fixes a handful of bugs found and fixed since v2.4.0. In
 particular, Git LFS no longer panic()'s after invalid API responses, can
index 2715645..004755c 100644 (file)
@@ -4,7 +4,7 @@ import (
        "os"
        "path/filepath"
 
-       "github.com/bgentry/go-netrc/netrc"
+       "github.com/git-lfs/go-netrc/netrc"
 )
 
 type netrcfinder interface {
index 634fc2b..4bb1bba 100644 (file)
@@ -12,7 +12,7 @@ var (
 )
 
 const (
-       Version = "2.4.1"
+       Version = "2.4.2"
 )
 
 func init() {
index 367060a..ceb0cf3 100644 (file)
@@ -1,3 +1,9 @@
+git-lfs (2.4.2) stable; urgency=low
+
+  * New upstream version
+
+ -- Taylor Blau <me@ttaylorr.com>  Mon, 28 May 2018 14:29:00 +0000
+
 git-lfs (2.4.1) stable; urgency=low
 
   * New upstream version
index a4cb1f4..b823f1e 100644 (file)
@@ -1,18 +1,18 @@
-hash: bad2138ca7787101a7a23af2464319cc580f4285e90c07d11eb9f90ad3bb9604
-updated: 2018-02-27T14:39:39.133796-08:00
+hash: 5d2fbd8be4931b982d29c6ac8df833f139b28ffdb44ca062948a2386e2096a4d
+updated: 2018-05-28T18:35:44.591993-07:00
 imports:
 - name: github.com/alexbrainman/sspi
   version: 4729b3d4d8581b2db83864d1018926e4154f9406
   subpackages:
   - ntlm
-- name: github.com/bgentry/go-netrc
-  version: 9fd32a8b3d3d3f9d43c341bfe098430e07609480
-  subpackages:
-  - netrc
 - name: github.com/davecgh/go-spew
   version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
   subpackages:
   - spew
+- name: github.com/git-lfs/go-netrc
+  version: e0e9ca483a183481412e6f5a700ff20a36177503
+  subpackages:
+  - netrc
 - name: github.com/git-lfs/wildmatch
   version: 8a0518641565a619e62a2738c7d4498fc345daf6
 - name: github.com/inconshreveable/mousetrap
index eee8a77..5e7758d 100644 (file)
@@ -1,7 +1,7 @@
 package: github.com/git-lfs/git-lfs
 import:
-- package: github.com/bgentry/go-netrc
-  version: 9fd32a8b3d3d3f9d43c341bfe098430e07609480
+- package: github.com/git-lfs/go-netrc
+  version: e0e9ca483a183481412e6f5a700ff20a36177503
   subpackages:
   - netrc
 - package: github.com/kr/pty
index 837e217..7d53e49 100644 (file)
@@ -9,8 +9,8 @@ import (
        "os"
        "strings"
 
-       "github.com/bgentry/go-netrc/netrc"
        "github.com/git-lfs/git-lfs/errors"
+       "github.com/git-lfs/go-netrc/netrc"
        "github.com/rubyist/tracerx"
 )
 
@@ -24,6 +24,10 @@ var (
 // authentication from netrc or git's credential helpers if necessary,
 // supporting basic and ntlm authentication.
 func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, error) {
+       return c.doWithAuth(remote, req, nil)
+}
+
+func (c *Client) doWithAuth(remote string, req *http.Request, via []*http.Request) (*http.Response, error) {
        req.Header = c.extraHeadersFor(req)
 
        apiEndpoint, access, credHelper, credsURL, creds, err := c.getCreds(remote, req)
@@ -31,7 +35,7 @@ func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, e
                return nil, err
        }
 
-       res, err := c.doWithCreds(req, credHelper, creds, credsURL, access)
+       res, err := c.doWithCreds(req, credHelper, creds, credsURL, access, via)
        if err != nil {
                if errors.IsAuthError(err) {
                        newAccess := getAuthAccess(res)
@@ -45,6 +49,12 @@ func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, e
                                        req.Header.Del("Authorization")
                                        credHelper.Reject(creds)
                                }
+
+                               // This case represents a rejected request that
+                               // should have been authenticated but wasn't. Do
+                               // not count this against our redirection
+                               // maximum, so do not recur through doWithAuth
+                               // and instead call DoWithAuth.
                                return c.DoWithAuth(remote, req)
                        }
                }
@@ -57,11 +67,11 @@ func (c *Client) DoWithAuth(remote string, req *http.Request) (*http.Response, e
        return res, err
 }
 
-func (c *Client) doWithCreds(req *http.Request, credHelper CredentialHelper, creds Creds, credsURL *url.URL, access Access) (*http.Response, error) {
+func (c *Client) doWithCreds(req *http.Request, credHelper CredentialHelper, creds Creds, credsURL *url.URL, access Access, via []*http.Request) (*http.Response, error) {
        if access == NTLMAccess {
                return c.doWithNTLM(req, credHelper, creds, credsURL)
        }
-       return c.do(req)
+       return c.do(req, "", via)
 }
 
 // getCreds fills the authorization header for the given request if possible,
index dd6c652..840c4d5 100644 (file)
@@ -85,16 +85,16 @@ func joinURL(prefix, suffix string) string {
 func (c *Client) Do(req *http.Request) (*http.Response, error) {
        req.Header = c.extraHeadersFor(req)
 
-       return c.do(req)
+       return c.do(req, "", nil)
 }
 
 // do performs an *http.Request respecting redirects, and handles the response
 // as defined in c.handleResponse. Notably, it does not alter the headers for
 // the request argument in any way.
-func (c *Client) do(req *http.Request) (*http.Response, error) {
+func (c *Client) do(req *http.Request, remote string, via []*http.Request) (*http.Response, error) {
        req.Header.Set("User-Agent", UserAgent)
 
-       res, err := c.doWithRedirects(c.httpClient(req.Host), req, nil)
+       res, err := c.doWithRedirects(c.httpClient(req.Host), req, remote, via)
        if err != nil {
                return res, err
        }
@@ -150,7 +150,7 @@ func (c *Client) extraHeaders(u *url.URL) map[string][]string {
        return m
 }
 
-func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, via []*http.Request) (*http.Response, error) {
+func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, remote string, via []*http.Request) (*http.Response, error) {
        tracedReq, err := c.traceRequest(req)
        if err != nil {
                return nil, err
@@ -220,7 +220,14 @@ func (c *Client) doWithRedirects(cli *http.Client, req *http.Request, via []*htt
                return res, err
        }
 
-       return c.doWithRedirects(cli, redirectedReq, via)
+       if len(req.Header.Get("Authorization")) > 0 {
+               // If the original request was authenticated (noted by the
+               // presence of the Authorization header), then recur through
+               // doWithAuth, retaining the requests via but only after
+               // authenticating the redirected request.
+               return c.doWithAuth(remote, redirectedReq, via)
+       }
+       return c.doWithRedirects(cli, redirectedReq, remote, via)
 }
 
 func (c *Client) httpClient(host string) *http.Client {
index e31a7e9..f5500f8 100644 (file)
@@ -1,11 +1,13 @@
 package lfsapi
 
 import (
+       "encoding/base64"
        "encoding/json"
        "fmt"
        "net"
        "net/http"
        "net/http/httptest"
+       "strings"
        "sync/atomic"
        "testing"
 
@@ -175,6 +177,80 @@ func TestClientRedirect(t *testing.T) {
        assert.EqualError(t, err, "lfsapi/client: refusing insecure redirect, https->http")
 }
 
+func TestClientRedirectReauthenticate(t *testing.T) {
+       var srv1, srv2 *httptest.Server
+       var called1, called2 uint32
+       var creds1, creds2 Creds
+
+       srv1 = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+               atomic.AddUint32(&called1, 1)
+
+               if hdr := r.Header.Get("Authorization"); len(hdr) > 0 {
+                       parts := strings.SplitN(hdr, " ", 2)
+                       typ, b64 := parts[0], parts[1]
+
+                       auth, err := base64.URLEncoding.DecodeString(b64)
+                       assert.Nil(t, err)
+                       assert.Equal(t, "Basic", typ)
+                       assert.Equal(t, "user1:pass1", string(auth))
+
+                       http.Redirect(w, r, srv2.URL+r.URL.Path, http.StatusMovedPermanently)
+                       return
+               }
+               w.WriteHeader(http.StatusUnauthorized)
+       }))
+
+       srv2 = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+               atomic.AddUint32(&called2, 1)
+
+               parts := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
+               typ, b64 := parts[0], parts[1]
+
+               auth, err := base64.URLEncoding.DecodeString(b64)
+               assert.Nil(t, err)
+               assert.Equal(t, "Basic", typ)
+               assert.Equal(t, "user2:pass2", string(auth))
+       }))
+
+       // Change the URL of srv2 to make it appears as if it is a different
+       // host.
+       srv2.URL = strings.Replace(srv2.URL, "127.0.0.1", "0.0.0.0", 1)
+
+       creds1 = Creds(map[string]string{
+               "protocol": "http",
+               "host":     strings.TrimPrefix(srv1.URL, "http://"),
+
+               "username": "user1",
+               "password": "pass1",
+       })
+       creds2 = Creds(map[string]string{
+               "protocol": "http",
+               "host":     strings.TrimPrefix(srv2.URL, "http://"),
+
+               "username": "user2",
+               "password": "pass2",
+       })
+
+       defer srv1.Close()
+       defer srv2.Close()
+
+       c, err := NewClient(NewContext(nil, nil, nil))
+       creds := newCredentialCacher()
+       creds.Approve(creds1)
+       creds.Approve(creds2)
+       c.Credentials = creds
+
+       req, err := http.NewRequest("GET", srv1.URL, nil)
+       require.Nil(t, err)
+
+       _, err = c.DoWithAuth("", req)
+       assert.Nil(t, err)
+
+       // called1 is 2 since LFS tries an unauthenticated request first
+       assert.EqualValues(t, 2, called1)
+       assert.EqualValues(t, 1, called2)
+}
+
 func TestNewClient(t *testing.T) {
        c, err := NewClient(NewContext(nil, nil, map[string]string{
                "lfs.dialtimeout":         "151",
index f40f641..3d2c655 100644 (file)
@@ -4,8 +4,8 @@ import (
        "os"
        "path/filepath"
 
-       "github.com/bgentry/go-netrc/netrc"
        "github.com/git-lfs/git-lfs/config"
+       "github.com/git-lfs/go-netrc/netrc"
 )
 
 type NetrcFinder interface {
index f07e7f0..88f495d 100644 (file)
@@ -6,7 +6,7 @@ import (
        "strings"
        "testing"
 
-       "github.com/bgentry/go-netrc/netrc"
+       "github.com/git-lfs/go-netrc/netrc"
 )
 
 func TestNetrcWithHostAndPort(t *testing.T) {
index 10b1ae7..0170bb9 100644 (file)
@@ -19,7 +19,7 @@ type ntmlCredentials struct {
 }
 
 func (c *Client) doWithNTLM(req *http.Request, credHelper CredentialHelper, creds Creds, credsURL *url.URL) (*http.Response, error) {
-       res, err := c.do(req)
+       res, err := c.do(req, "", nil)
        if err != nil && !errors.IsAuthError(err) {
                return res, err
        }
@@ -86,7 +86,7 @@ func (c *Client) ntlmSendMessage(req *http.Request, message []byte) (*http.Respo
 
        msg := base64.StdEncoding.EncodeToString(message)
        req.Header.Set("Authorization", "NTLM "+msg)
-       return c.do(req)
+       return c.do(req, "", nil)
 }
 
 func parseChallengeResponse(res *http.Response) ([]byte, error) {
index 74343b0..f0a4330 100644 (file)
@@ -1,5 +1,5 @@
 Name:           git-lfs
-Version:        2.4.1
+Version:        2.4.2
 Release:        1%{?dist}
 Summary:        Git extension for versioning large files
 
index 3efbe6b..845d484 100755 (executable)
@@ -259,6 +259,39 @@ begin_test "credentials from netrc"
 )
 end_test
 
+begin_test "credentials from netrc with unknown keyword"
+(
+  set -e
+
+  printf "machine localhost\nlogin netrcuser\nnot-a-key something\npassword netrcpass\n" >> "$NETRCFILE"
+  echo $HOME
+  echo "GITSERVER $GITSERVER"
+  cat $NETRCFILE
+
+  # prevent prompts on Windows particularly
+  export SSH_ASKPASS=
+
+  reponame="netrctest"
+  setup_remote_repo "$reponame"
+
+  clone_repo "$reponame" repo2
+
+  # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
+  git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
+  git lfs env
+
+  git lfs track "*.dat"
+  echo "push a" > a.dat
+  git add .gitattributes a.dat
+  git commit -m "add a.dat"
+
+  GIT_TRACE=1 git lfs push netrc master 2>&1 | tee push.log
+  grep "Uploading LFS objects: 100% (1/1), 7 B" push.log
+  echo "any git credential calls:"
+  [ "0" -eq "$(cat push.log | grep "git credential" | wc -l)" ]
+)
+end_test
+
 begin_test "credentials from netrc with bad password"
 (
   set -e
@@ -274,7 +307,7 @@ begin_test "credentials from netrc with bad password"
   reponame="netrctest"
   setup_remote_repo "$reponame"
 
-  clone_repo "$reponame" repo2
+  clone_repo "$reponame" repo3
 
   # Need a remote named "localhost" or 127.0.0.1 in netrc will interfere with the other auth
   git remote add "netrc" "$(echo $GITSERVER | sed s/127.0.0.1/localhost/)/netrctest"
@@ -16,6 +16,12 @@ machine ray login demo password mypassword
 
 machine weirdlogin login uname password pass#pass
 
+machine google.com
+  login alice@google.com
+  not-a-keyword
+  password secure
+  also-not-a-keyword
+
 default
        login anonymous
        password joe@example.com
@@ -24,6 +24,7 @@ const (
        tkMacdef
        tkComment
        tkWhitespace
+       tkUnknown
 )
 
 var keywords = map[string]tkType{
@@ -70,7 +71,7 @@ func (n *Netrc) MarshalText() (text []byte, err error) {
        // TODO(bgentry): not safe for concurrency
        for i := range n.tokens {
                switch n.tokens[i].kind {
-               case tkComment, tkDefault, tkWhitespace: // always append these types
+               case tkComment, tkDefault, tkWhitespace, tkUnknown: // always append these types
                        text = append(text, n.tokens[i].rawkind...)
                default:
                        if n.tokens[i].value != "" { // skip empty-value tokens
@@ -391,9 +392,11 @@ func parse(r io.Reader, pos int) (*Netrc, error) {
                t, err = newToken(rawb)
                if err != nil {
                        if currentMacro == nil {
-                               return nil, &Error{pos, err.Error()}
+                               t.kind = tkUnknown
+                               nrc.tokens = append(nrc.tokens, t)
+                       } else {
+                               currentMacro.rawvalue = append(currentMacro.rawvalue, rawb...)
                        }
-                       currentMacro.rawvalue = append(currentMacro.rawvalue, rawb...)
                        continue
                }
 
@@ -18,6 +18,7 @@ var expectedMachines = []*Machine{
        &Machine{Name: "mail.google.com", Login: "joe@gmail.com", Password: "somethingSecret", Account: "justagmail"},
        &Machine{Name: "ray", Login: "demo", Password: "mypassword", Account: ""},
        &Machine{Name: "weirdlogin", Login: "uname", Password: "pass#pass", Account: ""},
+       &Machine{Name: "google.com", Login: "alice@google.com", Password: "secure"},
        &Machine{Name: "", Login: "anonymous", Password: "joe@example.com", Account: ""},
 }
 var expectedMacros = Macros{
@@ -146,7 +147,7 @@ func TestFindMachine(t *testing.T) {
        if err != nil {
                t.Fatal(err)
        }
-       if !eqMachine(m, expectedMachines[3]) {
+       if !eqMachine(m, expectedMachines[4]) {
                t.Errorf("bad machine; expected %v, got %v\n", expectedMachines[3], m)
        }
        if !m.IsDefault() {
index 45692d6..8cc05ae 100644 (file)
@@ -4,7 +4,7 @@
                "FileVersion": {
                        "Major": 2,
                        "Minor": 4,
-                       "Patch": 1,
+                       "Patch": 2,
                        "Build": 0
                }
        },
@@ -13,7 +13,7 @@
                "FileDescription": "Git LFS",
                "LegalCopyright": "GitHub, Inc. and Git LFS contributors",
                "ProductName": "Git Large File Storage (LFS)",
-               "ProductVersion": "2.4.1"
+               "ProductVersion": "2.4.2"
        },
        "IconPath": "script/windows-installer/git-lfs-logo.ico"
 }