From 1fc3257f6e7627a11e37466cd449ca0533fc0666 Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Wed, 22 Jul 2015 10:58:30 -0700 Subject: [PATCH] updating gotuf dep with some better http error handling. Signed-off-by: David Lawrence (github: endophage) --- Godeps/Godeps.json | 2 +- .../endophage/gotuf/client/client.go | 12 +++++++- .../endophage/gotuf/store/httpstore.go | 28 +++++++++++++++++-- client/client.go | 6 ++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index bb89f04816..129dffce35 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -63,7 +63,7 @@ }, { "ImportPath": "github.com/endophage/gotuf", - "Rev": "5be7693587dc2f3c6b35fd1394fcc4e098b4f643" + "Rev": "5b7f722ae396b27c59ab5be5e7314a51d1813c29" }, { "ImportPath": "github.com/go-sql-driver/mysql", diff --git a/Godeps/_workspace/src/github.com/endophage/gotuf/client/client.go b/Godeps/_workspace/src/github.com/endophage/gotuf/client/client.go index 3fdc0a8dec..626507042d 100644 --- a/Godeps/_workspace/src/github.com/endophage/gotuf/client/client.go +++ b/Godeps/_workspace/src/github.com/endophage/gotuf/client/client.go @@ -239,6 +239,8 @@ func (c *Client) downloadTimestamp() error { if err == nil { version = ts.Signed.Version } + } else { + old = nil } } // unlike root, targets and snapshot, always try and download timestamps @@ -247,7 +249,15 @@ func (c *Client) downloadTimestamp() error { raw, err := c.remote.GetMeta(role, maxSize) var s *data.Signed if err != nil || len(raw) == 0 { - if err, ok := err.(*store.ErrMetaNotFound); ok { + if err, ok := err.(store.ErrMetaNotFound); ok { + return err + } + if old == nil { + if err == nil { + // couldn't retrieve data from server and don't have valid + // data in cache. + return store.ErrMetaNotFound{} + } return err } s = old diff --git a/Godeps/_workspace/src/github.com/endophage/gotuf/store/httpstore.go b/Godeps/_workspace/src/github.com/endophage/gotuf/store/httpstore.go index 213744b1c5..1287a6d7ab 100644 --- a/Godeps/_workspace/src/github.com/endophage/gotuf/store/httpstore.go +++ b/Godeps/_workspace/src/github.com/endophage/gotuf/store/httpstore.go @@ -14,6 +14,24 @@ import ( "github.com/Sirupsen/logrus" ) +type ErrServerUnavailable struct{} + +func (err ErrServerUnavailable) Error() string { + return "Unable to reach trust server at this time." +} + +type ErrShortRead struct{} + +func (err ErrShortRead) Error() string { + return "Trust server returned incompelete response." +} + +type ErrMaliciousServer struct{} + +func (err ErrMaliciousServer) Error() string { + return "Trust server returned a bad response." +} + // HTTPStore manages pulling and pushing metadata from and to a remote // service over HTTP. It assumes the URL structure of the remote service // maps identically to the structure of the TUF repo: @@ -67,12 +85,18 @@ func (s HTTPStore) GetMeta(name string, size int64) ([]byte, error) { return nil, err } defer resp.Body.Close() + if resp.ContentLength > size { + return nil, ErrMaliciousServer{} + } logrus.Debugf("%d when retrieving metadata for %s", resp.StatusCode, name) if resp.StatusCode == http.StatusNotFound { - return nil, &ErrMetaNotFound{} + return nil, ErrMetaNotFound{} } - b := io.LimitReader(resp.Body, int64(size)) + b := io.LimitReader(resp.Body, size) body, err := ioutil.ReadAll(b) + if resp.ContentLength > 0 && int64(len(body)) < resp.ContentLength { + return nil, ErrShortRead{} + } if err != nil { return nil, err diff --git a/client/client.go b/client/client.go index a0731d33a2..113c9d8d6e 100644 --- a/client/client.go +++ b/client/client.go @@ -308,7 +308,7 @@ func (r *NotaryRepository) Publish() error { // attempt to initialize the repo from the remote store c, err := r.bootstrapClient() if err != nil { - if _, ok := err.(*store.ErrMetaNotFound); ok { + if _, ok := err.(store.ErrMetaNotFound); ok { // if the remote store return a 404 (translated into ErrMetaNotFound), // the repo hasn't been initialized yet. Attempt to load it from disk. err := r.bootstrapRepo() @@ -506,7 +506,7 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) { // if remote store couldn't be setup, or we failed to get a root from it // load the root from cache (offline operation) if err != nil { - if err, ok := err.(*store.ErrMetaNotFound); ok { + if err, ok := err.(store.ErrMetaNotFound); ok { // if the error was MetaNotFound then we successfully contacted // the store and it doesn't know about the repo. return nil, err @@ -514,7 +514,7 @@ func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) { rootJSON, err = r.fileStore.GetMeta("root", maxSize) if err != nil { // if cache didn't return a root, we cannot proceed - return nil, &store.ErrMetaNotFound{} + return nil, store.ErrMetaNotFound{} } } root := &data.Signed{}