Skip to content
This repository has been archived by the owner on Feb 14, 2024. It is now read-only.

Commit

Permalink
add download method for updater (#20)
Browse files Browse the repository at this point in the history
* add download method for updater

Closes #13

In the process of adding the method also discovered and updated the potentially race-y usage of the repoManager struct.

Closes #16 but full fix should come in with #22
  • Loading branch information
groob authored Jun 27, 2017
1 parent 60c1fb4 commit 04e45b3
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 265 deletions.
13 changes: 13 additions & 0 deletions example/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func main() {
flServerCerts = flag.String("server-certificates", "../../test/server", "path to folder with server certs. must be named cert.pem and key.pem respectively")
flGUN = flag.String("gun", "kolide/greeter/darwin", "the globally unique identifier")
flBootstrap = flag.Bool("bootstrap", false, "set up local repository for the GUN from the local notary-server")
flDownoad = flag.String("download", "", "download a specific target")
)
flag.Parse()

Expand Down Expand Up @@ -88,6 +89,18 @@ func main() {
log.Fatal(http.ListenAndServeTLS(":8888", cert, key, nil))
}()

if *flDownoad != "" {
f, err := ioutil.TempFile(os.TempDir(), "osqueryd")
defer f.Close()
if err != nil {
log.Fatal(err)
}
fmt.Printf("downloading %s to %s\n", settings.TargetName, f.Name())
if err := update.Download("latest/target", f); err != nil {
log.Fatal(err)
}
}

fmt.Print("Hit enter to stop me: ")
fmt.Scanln()

Expand Down
69 changes: 69 additions & 0 deletions tuf/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package tuf

import (
"io"

"github.com/pkg/errors"
)

// Client is a TUF client.
type Client struct {
// Client wraps the private repoMan type which contains the actual
// methods for working with TUF repositories. In the future it might
// be worthwile to export the repoMan type as Client instead, but
// wrapping it reduces the amount of present refactoring work.
manager *repoMan
}

func NewClient(settings *Settings) (*Client, error) {
if settings.MaxResponseSize == 0 {
settings.MaxResponseSize = defaultMaxResponseSize
}
// check to see if Notary server is available
notary, err := newNotaryRepo(settings)
if err != nil {
return nil, errors.Wrap(err, "creating notary client")
}
err = notary.ping()
if err != nil {
return nil, errors.Wrap(err, "pinging notary server failed")
}
localRepo, err := newLocalRepo(settings.LocalRepoPath)
if err != nil {
return nil, errors.New("creating local tuf role repo")
}
// store intermediate state until all validation succeeds, then write
// changed roles to non-volitile storage
manager := newRepoMan(localRepo, notary, settings, notary.client)
return &Client{manager: manager}, nil
}

func (c *Client) Update() (files map[string]FileIntegrityMeta, latest bool, err error) {
latest, err = c.manager.refresh()
if err != nil {
return nil, latest, errors.Wrap(err, "refreshing state")
}

if err := c.manager.save(getTag()); err != nil {
return nil, latest, errors.Wrap(err, "unable to save tuf repo state")
}

files = c.manager.getLocalTargets()
return files, latest, nil
}

func (c *Client) Download(targetName string, destination io.Writer) error {
files := c.manager.getLocalTargets()
fim, ok := files[targetName]
if !ok {
return errNoSuchTarget
}
if err := c.manager.downloadTarget(targetName, &fim, destination); err != nil {
return errors.Wrap(err, "downloading target")
}
return nil
}

func (c *Client) Stop() {
c.manager.Stop()
}
21 changes: 8 additions & 13 deletions tuf/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import (
"crypto/sha256"
"crypto/sha512"
"encoding/base64"
"errors"
"hash"
"io"
"io/ioutil"
"time"

cjson "github.com/docker/go/canonical/json"
"github.com/pkg/errors"
)

// targetNameType is the path to the target. Mirror host + targetNameType is the
// download location of the file. For example if the mirror is https://releases.kolide.co
// and the targetNameType is kolide/agent/linux/installer then you'd download
// https://releases.kolide.co/kolide/agent/linux/installer
type targetNameType string
type keyID string
type hashingMethod string
type role string
Expand Down Expand Up @@ -150,11 +145,11 @@ type Targets struct {

// SignedTarget specifics of the Targets
type SignedTarget struct {
Type string `json:"_type"`
Delegations Delegations `json:"delegations"`
Expires time.Time `json:"expires"`
Targets map[targetNameType]FileIntegrityMeta `json:"targets"`
Version int `json:"version"`
Type string `json:"_type"`
Delegations Delegations `json:"delegations"`
Expires time.Time `json:"expires"`
Targets map[string]FileIntegrityMeta `json:"targets"`
Version int `json:"version"`
}

func (sr SignedTarget) canonicalJSON() ([]byte, error) {
Expand All @@ -176,7 +171,7 @@ func (sig *Signature) base64Decoded() ([]byte, error) {
// the binary footprint of the file hasn't been tampered with
type FileIntegrityMeta struct {
Hashes map[hashingMethod]string `json:"hashes"`
Length int `json:"length"`
Length int64 `json:"length"`
}

type hashInfo struct {
Expand Down Expand Up @@ -208,7 +203,7 @@ func (fim FileIntegrityMeta) verify(rdr io.Reader) error {
if err != nil {
return err
}
if length != int64(fim.Length) {
if length != fim.Length {
return errLengthIncorrect
}
for _, h := range hashes {
Expand Down
6 changes: 3 additions & 3 deletions tuf/roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func TestTargetsJson(t *testing.T) {
assert.Equal(t, 5, targets.Signed.Version)
target, ok := targets.Signed.Targets["1.0.0"]
require.True(t, ok)
assert.Equal(t, 3453, target.Length)
assert.Equal(t, int64(3453), target.Length)
hash, ok := target.Hashes[hashSHA256]
require.True(t, ok)
assert.Equal(t, "xdD9jvFLoCYvTNYiyDMyX054paEjI88NddSVAv8fZXI=", hash)
Expand Down Expand Up @@ -88,7 +88,7 @@ func TestSnapshotJson(t *testing.T) {
role role
sha256 string
sha512 string
length int
length int64
}{
{true, roleRoot, `hmw3Q5sat`, `EU+fVRkpw9n1UIzx1`, 2357},
{true, roleTargets, `nwg+cF2+A+Ybf`, `GGye6UL/7r+qz`, 727},
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestTimestampJson(t *testing.T) {
role role
sha256 string
sha512 string
length int
length int64
}{
{false, roleRoot, "", "", 0},
{false, roleTargets, "", "", 0},
Expand Down
Loading

0 comments on commit 04e45b3

Please sign in to comment.