From 4a05750c9a16f6d6f3747bc9a8826765d7fe4850 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Tue, 15 Dec 2020 10:54:49 -0800 Subject: [PATCH 001/115] Hello osquery! --- go.mod | 3 +++ main.go | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 go.mod create mode 100644 main.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000000..d5fc72e640 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/fleetdm/orbit + +go 1.15 diff --git a/main.go b/main.go new file mode 100644 index 0000000000..3946bbb935 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello osquery!") +} From 6901819fdf8f7bcb76ccf34165f3d1a371022984 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 16:53:44 -0800 Subject: [PATCH 002/115] Add beginning of process library Includes a testable wrapper around exec.Cmd that implements a wait with kill completion mechanism. --- go.mod | 6 ++ go.sum | 15 +++++ src/process/process.go | 103 ++++++++++++++++++++++++++++++++ src/process/process_mock.go | 62 +++++++++++++++++++ src/process/process_test.go | 116 ++++++++++++++++++++++++++++++++++++ 5 files changed, 302 insertions(+) create mode 100644 go.sum create mode 100644 src/process/process.go create mode 100644 src/process/process_mock.go create mode 100644 src/process/process_test.go diff --git a/go.mod b/go.mod index d5fc72e640..96949986f1 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,9 @@ module github.com/fleetdm/orbit go 1.15 + +require ( + github.com/oklog/run v1.1.0 + github.com/pkg/errors v0.9.1 + github.com/stretchr/testify v1.6.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000000..8fe4851396 --- /dev/null +++ b/go.sum @@ -0,0 +1,15 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/process/process.go b/src/process/process.go new file mode 100644 index 0000000000..c43a5a0f9b --- /dev/null +++ b/src/process/process.go @@ -0,0 +1,103 @@ +package main + +import ( + "context" + "fmt" + "os" + "os/exec" + "time" +) + +type ExecCmd interface { + Start() error + Wait() error + OsProcess() OsProcess +} + +type OsProcess interface { + Signal(os.Signal) error + Kill() error +} + +type execCmdWrapper struct { + *exec.Cmd +} + +func (e *execCmdWrapper) OsProcess() OsProcess { + return e.Process +} + +type Process struct { + ExecCmd +} + +func NewWithCmd(cmd *exec.Cmd) *Process { + return &Process{ExecCmd: &execCmdWrapper{Cmd: cmd}} +} + +func newWithMock(cmd ExecCmd) *Process { + return &Process{ExecCmd: cmd} +} + +// WaitOrKill waits for the already-started process by calling its Wait method. +// +// If the process does not return before ctx is done, WaitOrKill sends it the +// given interrupt signal. If killDelay is positive, WaitOrKill waits that +// additional period for Wait to return before sending os.Kill. +// +// Adapted from Go core: +// https://github.com/golang/go/blob/8981092d71aee273d27b0e11cf932a34d4d365c1/src/cmd/go/script_test.go#L1131-L1190 +func (p *Process) WaitOrKill(ctx context.Context, interrupt os.Signal, killDelay time.Duration) error { + if p.OsProcess() == nil { + return fmt.Errorf("WaitOrKill requires a non-nil OsProcess - missing Start call?") + } + + if interrupt == nil { + return fmt.Errorf("WaitOrKill requires a non-nil interrupt signal") + } + + errc := make(chan error) + go func() { + select { + case errc <- nil: + return + case <-ctx.Done(): + } + + err := p.OsProcess().Signal(interrupt) + if err == nil { + err = ctx.Err() // Report ctx.Err() as the reason we interrupted. + } else if err.Error() == "os: process already finished" { + errc <- nil + return + } + + if killDelay > 0 { + timer := time.NewTimer(killDelay) + select { + // Report ctx.Err() as the reason we interrupted the process... + case errc <- ctx.Err(): + timer.Stop() + return + // ...but after killDelay has elapsed, fall back to a stronger signal. + case <-timer.C: + } + + // Wait still hasn't returned. + // Kill the process harder to make sure that it exits. + // + // Ignore any error: if cmd.Process has already terminated, we still + // want to send ctx.Err() (or the error from the Interrupt call) + // to properly attribute the signal that may have terminated it. + _ = p.OsProcess().Kill() + } + + errc <- err + }() + + waitErr := p.Wait() + if interruptErr := <-errc; interruptErr != nil { + return interruptErr + } + return waitErr +} diff --git a/src/process/process_mock.go b/src/process/process_mock.go new file mode 100644 index 0000000000..d1223ec58d --- /dev/null +++ b/src/process/process_mock.go @@ -0,0 +1,62 @@ +package main + +import ( + "os" + + "github.com/stretchr/testify/mock" +) + +type mockOsProcess struct { + mock.Mock + OsProcess +} + +func (m *mockOsProcess) Signal(sig os.Signal) error { + args := m.Called(sig) + err := args.Error(0) + if err == nil { + return nil + } + return err.(error) +} + +func (m *mockOsProcess) Kill() error { + args := m.Called() + err := args.Error(0) + if err == nil { + return nil + } + return err.(error) +} + +type mockExecCmd struct { + mock.Mock + ExecCmd +} + +func (m *mockExecCmd) Start() error { + args := m.Called() + err := args.Error(0) + if err == nil { + return nil + } + return err.(error) +} + +func (m *mockExecCmd) Wait() error { + args := m.Called() + err := args.Error(0) + if err == nil { + return nil + } + return err.(error) +} + +func (m *mockExecCmd) OsProcess() OsProcess { + args := m.Called() + proc := args.Get(0) + if proc == nil { + return nil + } + return proc.(OsProcess) +} diff --git a/src/process/process_test.go b/src/process/process_test.go new file mode 100644 index 0000000000..b7910b510d --- /dev/null +++ b/src/process/process_test.go @@ -0,0 +1,116 @@ +package main + +import ( + "context" + "fmt" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestWaitOrKillNilProcess(t *testing.T) { + // Process not started + mockCmd := &mockExecCmd{} + defer mock.AssertExpectationsForObjects(t, mockCmd) + mockCmd.On("OsProcess").Return(nil) + + p := newWithMock(mockCmd) + err := p.WaitOrKill(context.Background(), os.Interrupt, 1*time.Second) + require.Error(t, err) + assert.Contains(t, err.Error(), "non-nil OsProcess") +} + +func TestWaitOrKillNilSignal(t *testing.T) { + // Nil signal provided + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + + p := newWithMock(mockCmd) + err := p.WaitOrKill(context.Background(), nil, 10*time.Millisecond) + require.Error(t, err) + assert.Contains(t, err.Error(), "non-nil interrupt") +} + +func TestWaitOrKillProcessCompleted(t *testing.T) { + // Process already completed + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + mockCmd.On("Wait").Return(nil) + + p := newWithMock(mockCmd) + err := p.WaitOrKill(context.Background(), os.Interrupt, 10*time.Millisecond) + require.NoError(t, err) +} + +func TestWaitOrKillProcessCompletedError(t *testing.T) { + // Process already completed with error + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + mockCmd.On("Wait").After(10 * time.Millisecond).Return(fmt.Errorf("super bad")) + + p := newWithMock(mockCmd) + err := p.WaitOrKill(context.Background(), os.Interrupt, 10*time.Millisecond) + require.Error(t, err) + assert.Contains(t, err.Error(), "super bad") +} + +func TestWaitOrKillWait(t *testing.T) { + // Process completes after the wait call and after the signal is sent + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + mockCmd.On("Wait").After(5 * time.Millisecond).Return(nil) + mockProcess.On("Signal", os.Interrupt).Return(nil) + + p := newWithMock(mockCmd) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err := p.WaitOrKill(ctx, os.Interrupt, 10*time.Millisecond) + require.Error(t, err) + assert.Contains(t, err.Error(), "context canceled") +} + +func TestWaitOrKillWaitSignalCompleted(t *testing.T) { + // Process completes after the wait call and before the signal is sent + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + mockCmd.On("Wait").After(10 * time.Millisecond).Return(nil) + mockProcess.On("Signal", os.Interrupt).Return(fmt.Errorf("os: process already finished")) + + p := newWithMock(mockCmd) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err := p.WaitOrKill(ctx, os.Interrupt, 5*time.Millisecond) + require.NoError(t, err) +} + +func TestWaitOrKillWaitKilled(t *testing.T) { + // Process is killed after the wait call and signal + mockCmd := &mockExecCmd{} + mockProcess := &mockOsProcess{} + defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) + mockCmd.On("OsProcess").Return(mockProcess) + mockCmd.On("Wait").After(10 * time.Millisecond).Return(fmt.Errorf("killed")) + mockProcess.On("Signal", os.Interrupt).Return(nil) + mockProcess.On("Kill").Return(nil) + + p := newWithMock(mockCmd) + ctx, cancel := context.WithCancel(context.Background()) + cancel() + err := p.WaitOrKill(ctx, os.Interrupt, 5*time.Millisecond) + require.Error(t, err) + assert.Contains(t, err.Error(), "context canceled") +} From d562f82718e22b33a1fd8fc06ad294f8a4534433 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 16:59:58 -0800 Subject: [PATCH 003/115] Refactor WaitOrKill into simplified StopOrKill Use a default stop signal set by the GOOS. --- src/process/process.go | 24 +++++++++++++++------ src/process/process_test.go | 42 +++++++++++++------------------------ 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/process/process.go b/src/process/process.go index c43a5a0f9b..665edc48ec 100644 --- a/src/process/process.go +++ b/src/process/process.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "runtime" "time" ) @@ -47,15 +48,11 @@ func newWithMock(cmd ExecCmd) *Process { // // Adapted from Go core: // https://github.com/golang/go/blob/8981092d71aee273d27b0e11cf932a34d4d365c1/src/cmd/go/script_test.go#L1131-L1190 -func (p *Process) WaitOrKill(ctx context.Context, interrupt os.Signal, killDelay time.Duration) error { +func (p *Process) StopOrKill(ctx context.Context, killDelay time.Duration) error { if p.OsProcess() == nil { return fmt.Errorf("WaitOrKill requires a non-nil OsProcess - missing Start call?") } - if interrupt == nil { - return fmt.Errorf("WaitOrKill requires a non-nil interrupt signal") - } - errc := make(chan error) go func() { select { @@ -64,7 +61,7 @@ func (p *Process) WaitOrKill(ctx context.Context, interrupt os.Signal, killDelay case <-ctx.Done(): } - err := p.OsProcess().Signal(interrupt) + err := p.OsProcess().Signal(stopSignal()) if err == nil { err = ctx.Err() // Report ctx.Err() as the reason we interrupted. } else if err.Error() == "os: process already finished" { @@ -101,3 +98,18 @@ func (p *Process) WaitOrKill(ctx context.Context, interrupt os.Signal, killDelay } return waitErr } + +// stopSignal returns the appropriate signal to use to request that a process +// stop execution. +// +// Copied from Go core: +// https://github.com/golang/go/blob/8981092d71aee273d27b0e11cf932a34d4d365c1/src/cmd/go/script_test.go#L1119-L1129 +func stopSignal() os.Signal { + if runtime.GOOS == "windows" { + // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on + // Windows; using it with os.Process.Signal will return an error.” + // Fall back to Kill instead. + return os.Kill + } + return os.Interrupt +} diff --git a/src/process/process_test.go b/src/process/process_test.go index b7910b510d..34de86d65a 100644 --- a/src/process/process_test.go +++ b/src/process/process_test.go @@ -3,7 +3,6 @@ package main import ( "context" "fmt" - "os" "testing" "time" @@ -19,25 +18,12 @@ func TestWaitOrKillNilProcess(t *testing.T) { mockCmd.On("OsProcess").Return(nil) p := newWithMock(mockCmd) - err := p.WaitOrKill(context.Background(), os.Interrupt, 1*time.Second) + err := p.StopOrKill(context.Background(), 1*time.Second) require.Error(t, err) assert.Contains(t, err.Error(), "non-nil OsProcess") } -func TestWaitOrKillNilSignal(t *testing.T) { - // Nil signal provided - mockCmd := &mockExecCmd{} - mockProcess := &mockOsProcess{} - defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) - mockCmd.On("OsProcess").Return(mockProcess) - - p := newWithMock(mockCmd) - err := p.WaitOrKill(context.Background(), nil, 10*time.Millisecond) - require.Error(t, err) - assert.Contains(t, err.Error(), "non-nil interrupt") -} - -func TestWaitOrKillProcessCompleted(t *testing.T) { +func TestStopOrKillProcessCompleted(t *testing.T) { // Process already completed mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -46,11 +32,11 @@ func TestWaitOrKillProcessCompleted(t *testing.T) { mockCmd.On("Wait").Return(nil) p := newWithMock(mockCmd) - err := p.WaitOrKill(context.Background(), os.Interrupt, 10*time.Millisecond) + err := p.StopOrKill(context.Background(), 10*time.Millisecond) require.NoError(t, err) } -func TestWaitOrKillProcessCompletedError(t *testing.T) { +func TestStopOrKillProcessCompletedError(t *testing.T) { // Process already completed with error mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -59,58 +45,58 @@ func TestWaitOrKillProcessCompletedError(t *testing.T) { mockCmd.On("Wait").After(10 * time.Millisecond).Return(fmt.Errorf("super bad")) p := newWithMock(mockCmd) - err := p.WaitOrKill(context.Background(), os.Interrupt, 10*time.Millisecond) + err := p.StopOrKill(context.Background(), 10*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "super bad") } -func TestWaitOrKillWait(t *testing.T) { +func TestStopOrKillWait(t *testing.T) { // Process completes after the wait call and after the signal is sent mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) mockCmd.On("OsProcess").Return(mockProcess) mockCmd.On("Wait").After(5 * time.Millisecond).Return(nil) - mockProcess.On("Signal", os.Interrupt).Return(nil) + mockProcess.On("Signal", stopSignal()).Return(nil) p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.WaitOrKill(ctx, os.Interrupt, 10*time.Millisecond) + err := p.StopOrKill(ctx, 10*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "context canceled") } -func TestWaitOrKillWaitSignalCompleted(t *testing.T) { +func TestStopOrKillWaitSignalCompleted(t *testing.T) { // Process completes after the wait call and before the signal is sent mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) mockCmd.On("OsProcess").Return(mockProcess) mockCmd.On("Wait").After(10 * time.Millisecond).Return(nil) - mockProcess.On("Signal", os.Interrupt).Return(fmt.Errorf("os: process already finished")) + mockProcess.On("Signal", stopSignal()).Return(fmt.Errorf("os: process already finished")) p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.WaitOrKill(ctx, os.Interrupt, 5*time.Millisecond) + err := p.StopOrKill(ctx, 5*time.Millisecond) require.NoError(t, err) } -func TestWaitOrKillWaitKilled(t *testing.T) { +func TestStopOrKillWaitKilled(t *testing.T) { // Process is killed after the wait call and signal mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} defer mock.AssertExpectationsForObjects(t, mockCmd, mockProcess) mockCmd.On("OsProcess").Return(mockProcess) mockCmd.On("Wait").After(10 * time.Millisecond).Return(fmt.Errorf("killed")) - mockProcess.On("Signal", os.Interrupt).Return(nil) + mockProcess.On("Signal", stopSignal()).Return(nil) mockProcess.On("Kill").Return(nil) p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.WaitOrKill(ctx, os.Interrupt, 5*time.Millisecond) + err := p.StopOrKill(ctx, 5*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "context canceled") } From 0b60d25bad3409fa7cdea58ddf33896d1c9ea9d4 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 16 Dec 2020 17:03:06 -0800 Subject: [PATCH 004/115] Add GitHub Actions for Go tests --- .github/workflows/go.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/go.yml diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000000..9815a6697f --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,32 @@ +name: Go + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + + build: + name: Build + runs-on: ubuntu-latest + steps: + + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ^1.15 + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + go get -v -t -d ./... + + - name: Build + run: go build -v ./... + + - name: Test + run: go test -v ./... From 7aa5aad852670e4b67fa52546897dedbe80f55c2 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 17:06:47 -0800 Subject: [PATCH 005/115] Fix package name for process package --- src/process/process.go | 2 +- src/process/process_mock.go | 2 +- src/process/process_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/process/process.go b/src/process/process.go index 665edc48ec..db77ae44d2 100644 --- a/src/process/process.go +++ b/src/process/process.go @@ -1,4 +1,4 @@ -package main +package process import ( "context" diff --git a/src/process/process_mock.go b/src/process/process_mock.go index d1223ec58d..8e0ee77c1a 100644 --- a/src/process/process_mock.go +++ b/src/process/process_mock.go @@ -1,4 +1,4 @@ -package main +package process import ( "os" diff --git a/src/process/process_test.go b/src/process/process_test.go index 34de86d65a..8282de64ff 100644 --- a/src/process/process_test.go +++ b/src/process/process_test.go @@ -1,4 +1,4 @@ -package main +package process import ( "context" From 6fd37f9f1ffefaa409e6470dde37582deb71cc81 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 17:11:22 -0800 Subject: [PATCH 006/115] Add golangci-lint action --- .github/workflows/golangci-lint.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/golangci-lint.yml diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 0000000000..99a2b6d485 --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,19 @@ +name: golangci-lint +on: + push: + branches: + - main + pull_request: +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + # Required: the version of golangci-lint is required and must be + # specified without patch version: we always use the latest patch + # version. + version: v1.33 From f7275e59448ea2a18f02f5b3dd850f318f3d58d0 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 17:12:52 -0800 Subject: [PATCH 007/115] Add .gitattributes for Go line endings --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..d207b1802b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.go text eol=lf From 5ca76b193a94ab15ca18c68ea06f3c672042f2aa Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 16 Dec 2020 19:24:23 -0800 Subject: [PATCH 008/115] Add initial pattern for osquery execution --- main.go | 29 ++++++++++++++++++++- src/osquery/flags.go | 21 +++++++++++++++ src/osquery/osquery.go | 58 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/osquery/flags.go create mode 100644 src/osquery/osquery.go diff --git a/main.go b/main.go index 3946bbb935..84bf80a9a1 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,34 @@ package main -import "fmt" +import ( + "context" + "fmt" + "log" + "os" + "os/exec" + + "github.com/fleetdm/orbit/src/osquery" + "github.com/oklog/run" +) func main() { fmt.Println("Hello osquery!") + + osqueryPath, err := exec.LookPath("osqueryd") + if err != nil { + log.Fatalf("no osquery found: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + var g run.Group + g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) + + r, _ := osquery.NewRunner() + g.Add(r.Execute, r.Interrupt) + + err = g.Run() + fmt.Println(err) + + _, _ = osqueryPath, cancel + //cmd := exec.CommandContext() } diff --git a/src/osquery/flags.go b/src/osquery/flags.go new file mode 100644 index 0000000000..647fc736e1 --- /dev/null +++ b/src/osquery/flags.go @@ -0,0 +1,21 @@ +package osquery + +func fleetFlags(hostname string) []string { + return []string{ + "--tls_hostname=" + hostname, + "--enroll_tls_endpoint=/api/v1/osquery/enroll", + "--config_plugin=tls", + "--config_tls_endpoint=/api/v1/osquery/config", + "--disable_distributed=false", + "--distributed_plugin=tls", + "--distributed_tls_max_attempts=10", + "--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read", + "--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write", + "--logger_plugin=tls", + "--logger_tls_endpoint=/api/v1/osquery/log", + "--disable_carver=false", + "--carver_start_endpoint=/api/v1/osquery/carve/begin", + "--carver_continue_endpoint=/api/v1/osquery/carve/block", + "--carver_block_size=2000000", + } +} diff --git a/src/osquery/osquery.go b/src/osquery/osquery.go new file mode 100644 index 0000000000..f53a4a0c40 --- /dev/null +++ b/src/osquery/osquery.go @@ -0,0 +1,58 @@ +package osquery + +import ( + "context" + "log" + "os" + "os/exec" + "time" + + "github.com/fleetdm/orbit/src/process" + "github.com/pkg/errors" +) + +type Runner struct { + proc *process.Process + cmd *exec.Cmd + cancel func() +} + +func NewRunner() (*Runner, error) { + r := &Runner{} + + // TODO set path and flags appropriately + cmd := exec.Command( + "osqueryd", + "--pidfile=/tmp/osquery.pid", + "--database_path=/tmp/osquery.test.db", + "--extensions_socket=/tmp/osquery.em", + "--config_path=/tmp/osquery.conf", + "--logger_path=/tmp", + ) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + r.cmd = cmd + r.proc = process.NewWithCmd(cmd) + + return r, nil +} + +func (r *Runner) Execute() error { + if err := r.proc.Start(); err != nil { + return errors.Wrap(err, "start osquery") + } + + ctx, cancel := context.WithCancel(context.Background()) + r.cancel = cancel + if err := r.proc.StopOrKill(ctx, 10*time.Second); err != nil { + return errors.Wrap(err, "osquery exited with error") + } + + return errors.New("osquery exited unexpectedly") +} + +func (r *Runner) Interrupt(err error) { + log.Printf("interrupt osquery") + r.cancel() +} From 08adb328a569aee3d073e4b832370ee7e71c8f4c Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Thu, 17 Dec 2020 14:48:12 -0800 Subject: [PATCH 009/115] Add flags for connecting to Fleet server Connection only works currently if the Fleet server has a TLS cert that is trusted by osquery. --- main.go | 4 +++- src/osquery/flags.go | 2 +- src/osquery/osquery.go | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 84bf80a9a1..7c967445fc 100644 --- a/main.go +++ b/main.go @@ -23,7 +23,9 @@ func main() { var g run.Group g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) - r, _ := osquery.NewRunner() + r, _ := osquery.NewRunner( + osquery.WithFlags(osquery.FleetFlags("localhost:8080")), + ) g.Add(r.Execute, r.Interrupt) err = g.Run() diff --git a/src/osquery/flags.go b/src/osquery/flags.go index 647fc736e1..04bffea54b 100644 --- a/src/osquery/flags.go +++ b/src/osquery/flags.go @@ -1,6 +1,6 @@ package osquery -func fleetFlags(hostname string) []string { +func FleetFlags(hostname string) []string { return []string{ "--tls_hostname=" + hostname, "--enroll_tls_endpoint=/api/v1/osquery/enroll", diff --git a/src/osquery/osquery.go b/src/osquery/osquery.go index f53a4a0c40..ff2d2eb4ae 100644 --- a/src/osquery/osquery.go +++ b/src/osquery/osquery.go @@ -17,7 +17,7 @@ type Runner struct { cancel func() } -func NewRunner() (*Runner, error) { +func NewRunner(options ...func(*Runner) error) (*Runner, error) { r := &Runner{} // TODO set path and flags appropriately @@ -35,9 +35,23 @@ func NewRunner() (*Runner, error) { r.cmd = cmd r.proc = process.NewWithCmd(cmd) + for _, option := range options { + err := option(r) + if err != nil { + return nil, errors.Wrap(err, "apply option") + } + } + return r, nil } +func WithFlags(flags []string) func(*Runner) error { + return func(r *Runner) error { + r.cmd.Args = append(r.cmd.Args, flags...) + return nil + } +} + func (r *Runner) Execute() error { if err := r.proc.Start(); err != nil { return errors.Wrap(err, "start osquery") From 9302a569f21fc4b809e040047d4ffb9539957798 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Thu, 17 Dec 2020 15:31:53 -0800 Subject: [PATCH 010/115] Implement retrieval of server certificate at startup This will allow a --insecure flag by writing the retrieved cert to a file and passing it to osquery. --- go.mod | 2 ++ go.sum | 7 ++++ main.go | 19 ++++++++++- src/certificate/certificate.go | 36 ++++++++++++++++++++ src/certificate/certificate_test.go | 48 ++++++++++++++++++++++++++ src/certificate/testdata/test.crt | 28 ++++++++++++++++ src/certificate/testdata/test.key | 52 +++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 src/certificate/certificate.go create mode 100644 src/certificate/certificate_test.go create mode 100644 src/certificate/testdata/test.crt create mode 100644 src/certificate/testdata/test.key diff --git a/go.mod b/go.mod index 96949986f1..737ca87bc2 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/fleetdm/orbit go 1.15 require ( + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 + github.com/kr/pretty v0.2.1 // indirect github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.6.1 diff --git a/go.sum b/go.sum index 8fe4851396..72f8244e7c 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,12 @@ +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/main.go b/main.go index 7c967445fc..6bb9583290 100644 --- a/main.go +++ b/main.go @@ -3,14 +3,21 @@ package main import ( "context" "fmt" + "io/ioutil" "log" "os" "os/exec" + "github.com/fleetdm/orbit/src/certificate" "github.com/fleetdm/orbit/src/osquery" "github.com/oklog/run" ) +const ( + serverURL = "localhost:8080" + certPath = "/tmp/fleet.pem" +) + func main() { fmt.Println("Hello osquery!") @@ -19,12 +26,22 @@ func main() { log.Fatalf("no osquery found: %v", err) } + serverCert, err := certificate.FetchPEM(serverURL) + if err != nil { + log.Fatalf("retrieve server cert: %v", err) + } + err = ioutil.WriteFile(certPath, serverCert, os.ModePerm) + if err != nil { + log.Fatalf("write server cert: %v", err) + } + ctx, cancel := context.WithCancel(context.Background()) var g run.Group g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) r, _ := osquery.NewRunner( - osquery.WithFlags(osquery.FleetFlags("localhost:8080")), + osquery.WithFlags(osquery.FleetFlags(serverURL)), + osquery.WithFlags([]string{"--tls_server_certs", certPath}), ) g.Add(r.Execute, r.Interrupt) diff --git a/src/certificate/certificate.go b/src/certificate/certificate.go new file mode 100644 index 0000000000..9b7a4a139c --- /dev/null +++ b/src/certificate/certificate.go @@ -0,0 +1,36 @@ +// Package certificate contains functions for handling TLS certificates. +package certificate + +import ( + "bytes" + "crypto/tls" + "encoding/pem" + + "github.com/pkg/errors" +) + +// FetchPEM retrieves the certificate chain presented by the server listening at +// hostname in PEM format. +// +// Adapted from https://stackoverflow.com/a/46735876/491710 +func FetchPEM(hostname string) ([]byte, error) { + conn, err := tls.Dial("tcp", hostname, &tls.Config{ + InsecureSkipVerify: true, + }) + if err != nil { + return nil, errors.Wrap(err, "dial server to fetch PEM") + } + defer conn.Close() + + var b bytes.Buffer + for _, cert := range conn.ConnectionState().PeerCertificates { + err := pem.Encode(&b, &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Raw, + }) + if err != nil { + return nil, errors.Wrap(err, "encode PEM") + } + } + return b.Bytes(), nil +} diff --git a/src/certificate/certificate_test.go b/src/certificate/certificate_test.go new file mode 100644 index 0000000000..66fe400d74 --- /dev/null +++ b/src/certificate/certificate_test.go @@ -0,0 +1,48 @@ +package certificate + +import ( + "io/ioutil" + "net" + "net/http" + "path/filepath" + "strconv" + "testing" + "time" + + "github.com/bmizerany/assert" + "github.com/stretchr/testify/require" +) + +func TestFetchPEMInvalidHostname(t *testing.T) { + t.Parallel() + + _, err := FetchPEM("foobar") + require.Error(t, err) +} + +func TestFetchPEM(t *testing.T) { + t.Parallel() + + certPath := filepath.Join("testdata", "test.crt") + keyPath := filepath.Join("testdata", "test.key") + expectedCert, err := ioutil.ReadFile(certPath) + require.NoError(t, err) + + var port int + go func() { + // Assign any available port + listener, err := net.Listen("tcp", "localhost:0") + require.NoError(t, err) + port = listener.Addr().(*net.TCPAddr).Port + defer listener.Close() + + err = http.ServeTLS(listener, nil, certPath, keyPath) + require.NoError(t, err) + }() + // Sleep to allow the goroutine to run and start the server. + time.Sleep(10 * time.Millisecond) + + pem, err := FetchPEM("localhost:" + strconv.Itoa(port)) + require.NoError(t, err) + assert.Equal(t, expectedCert, pem) +} diff --git a/src/certificate/testdata/test.crt b/src/certificate/testdata/test.crt new file mode 100644 index 0000000000..0f4f781a1c --- /dev/null +++ b/src/certificate/testdata/test.crt @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIErjCCApYCCQCj1g+mDUoEQjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5s +b2NhbGhvc3Q6ODU0MzAeFw0yMDEyMTcyMzA4MzJaFw00ODA1MDMyMzA4MzJaMBkx +FzAVBgNVBAMMDmxvY2FsaG9zdDo4NTQzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAyAThP2RVyrZd1hnrjoz0f87dT3xC6PDFMf+SG55A8YhtvylHG3Ph +Xq8TZ6oFhWmqLjllAGKlfJRcTnqY9f3mtDFvNt5yTu7Ot32VL5viZobp5fw0Wfcu +G2rKENZ5/3r6pE5iD2oRU5CxGsdnjRhKfVwK1ayF60hY23xY5TE+RVnyvuqsRMWU +2vTD3rx8k9g1/kJwkujG0eL3K3NslamM5yWxsRdUk0MCQDGlr176zqToUIhMqQLR +vkKw1hm+m9OQHHn3pucUdPbQynWMVEUKCCF19wtqW2rUW9POgkPD4cPf3D999rvK +Y08XhzXmS74bAbDXBKHCFAQFFJUseSNEDjIBn/gfMH6KX0x1kiRixj/hdel9VdkO +dUl/AScfOTg71DxjQDbp/EW/diufNZwadXbBjiKeys8Zi9ISt4WQmXc08FTRCb9T +6rghenH2UBOT9zZn8yIoq38WfZ2dUmJPhIdEh27GOa/ets1psNg8lh+bEDKmDstd +6/SXlHR4Pfhqy4cqppG09Z/Hl6fgyr5U4/sdWN4gm/ZkbTGgPGJ2fQEuuuEsFXC2 +US9aJcEC4rw103yNr7/4P9u3U+iHGbq8wOFCEtf4p4mi/9S1Txsupnd/hbla2k2W +vNYhzqbbatf/A6ahc8Vee8x+Zd/fOcuk0khb8evq/TnBJIsw67aXPEECAwEAATAN +BgkqhkiG9w0BAQsFAAOCAgEAhYWB/mrNLZi1zru0W1gmfuSE3wBrN0G5Ce/alNi6 +MwHoQiBCxZmmYndbXEaXtwhsLoV7mlOYdYr1DiK94usT8g9kj4kymYsl0jPdM+1w +PPARBoPeqpHQBSYbAaB9Iqx1Wc/I5g/kwgrtoPM1Z3y7f2277BqeoxkwhVbC0aLC +cYkk+tzK4+sPfrW/onLfVuKsrVcoFnDsg/aa3rKdTcTsTwrJUF5S1hiK2CSkpJbx +60C4Zu7fUYFHbjcorsy+dSVX26+56sazS8o6Gpa+orPjLybFazCX806gPWmKQW48 +xkIpIJG0nocvqesUBEbJX/FKuAJ/yLl5P9uGJtjNlK4j/uhm9f5M49KoTSSAQ4A1 +Wm/2cBVPokGJ1c+SVGPHgu6QdBvVXznG/CI42cKwj4T0H4wwcah4lw3R9Vy6EqNW +13h20qs/2MnZ0GL2po3M9vYlV6x4dQPz+lXVlez2h1EkI4muffvz+Ql4zgkkAdUO +f+H+eC+m8Hf3/dtWhXdgoOFvMOROQIgYU+W+H6TXrGKwd7n/UkvxJEgNgXfcXlug +qICkuCVW2Z9BaIZiW9X12aNlEPUIgTxbNSYv/gZRXZ54St5DKmUJd5vuV1gm+xxA ++8Lr0uIAxknZGE1OAlADxwwXSJGjAC0m/13X/L/Kb5kd4DyiQvnyVcFfkwSp/xbd +Ihw= +-----END CERTIFICATE----- diff --git a/src/certificate/testdata/test.key b/src/certificate/testdata/test.key new file mode 100644 index 0000000000..266956c43a --- /dev/null +++ b/src/certificate/testdata/test.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDIBOE/ZFXKtl3W +GeuOjPR/zt1PfELo8MUx/5IbnkDxiG2/KUcbc+FerxNnqgWFaaouOWUAYqV8lFxO +epj1/ea0MW823nJO7s63fZUvm+Jmhunl/DRZ9y4basoQ1nn/evqkTmIPahFTkLEa +x2eNGEp9XArVrIXrSFjbfFjlMT5FWfK+6qxExZTa9MPevHyT2DX+QnCS6MbR4vcr +c2yVqYznJbGxF1STQwJAMaWvXvrOpOhQiEypAtG+QrDWGb6b05Acefem5xR09tDK +dYxURQoIIXX3C2pbatRb086CQ8Phw9/cP332u8pjTxeHNeZLvhsBsNcEocIUBAUU +lSx5I0QOMgGf+B8wfopfTHWSJGLGP+F16X1V2Q51SX8BJx85ODvUPGNANun8Rb92 +K581nBp1dsGOIp7KzxmL0hK3hZCZdzTwVNEJv1PquCF6cfZQE5P3NmfzIiirfxZ9 +nZ1SYk+Eh0SHbsY5r962zWmw2DyWH5sQMqYOy13r9JeUdHg9+GrLhyqmkbT1n8eX +p+DKvlTj+x1Y3iCb9mRtMaA8YnZ9AS664SwVcLZRL1olwQLivDXTfI2vv/g/27dT +6IcZurzA4UIS1/iniaL/1LVPGy6md3+FuVraTZa81iHOpttq1/8DpqFzxV57zH5l +3985y6TSSFvx6+r9OcEkizDrtpc8QQIDAQABAoICAQCQau2Tzsce+TOhfc+VenKi +wWMLnAXXmNhYtFXzOP1dJ4tOBejAipfDvJc/NwSLgnKMs4YYlCE2ZQyM4XoFyxBD +NJo/PLe+BDEfTT5lRKFgM7M4CjRmbNFOnHlPVPx7GXlVHv8wb/4YnxUw5579wfcu +skFkbA+5hOAbgZnRyg9TFZHuhRRjB2HmAepWrTMpsGezsJcFi6raKo0aQ1m4adZB +ova8jcLUHQLIBNDDYcmnYGwYkYEAWvfD7vUtcSMt8cBQv0Ovr5MWrIquU9dBlSOc +IUTCXeyqGuU/dBvb9D+/h6TfqrwxZP/JWnb7elBQie+H9f4Z6w1tVEWyyc51nJ/q +dQk63N3Kji+hXetR6tjAADwMKvJKn1Fd4xzgPt0OPHQu1J+kt2LXpdt78ynoPivz +eH1Ejf43YzSf6Zm8zisyfgDt9XBauNjosrDhrzvtMNAIYEA1jkZ0f0YUjHT4lltF +K1R9nl3MQGEQ1AfG4XaCfMRwTSKgxf8HWNYxWexQGvZRz62QKW4neLWjPYBM+jgt +em70efwjtXyy34rE7t4ItkphyvpnN1WFKLCve/Jpg5Ds4QzImqnHGnDIIQ8F+cNS +TXFblNOHcB5MgQI1I4Z08Ibq6a/2nYEpZZtBElug22hTTuYdo5vfiMTPsFdOosV+ +acbzawQScBCVUd5WhI1qnQKCAQEA6RJW9LbrUXxMEfZEbt9ucvS4Q0gkR/Fo7zGo +nEHc1MQlW93FPXOo/af41pN93V4c0k2M7cmB2iuGdqgxaPlRJDDHLFx4lF9gFNIS +GoxwKalMl+mTZrt9+f8zg/R/rQIwxpvYmpFhmtUbYHO37f+bwkMsZdbhw4bLEHSA +aPJup6LWJx6D+WnwgVABx2b4kaKGxlxVWBwr1a+NG0H18G4gnCgu3Cpx3Yaw/+cN +jLDy3ypPnkrVW72dyj24WtIfZc4rk9UkAJbwMtJXshYwbx+Ha0UD03dhlD1R50iz +ldvxSPkygNuJvgK34mFMS/Bga6PjRvlB9KHf7AeyE8ePsW56pwKCAQEA27Ildo1W +fmqS5fHXZ90lVzY37ZjKT9+OWsYq3dDievHtjdCXmsALAoXQKwE27i/C+a4AKSuU +SjsHCdV345ne0M3PrFR5OiCLVSRfqyBAetXkBic37W/xj7PTcBaWj/6u6iwgcQrq +/rEwXWdPCtT1Xp7ZI5kq38CuH0yAmQqnhzybTXj4g+f3mvgK+jxcG39KAJqQk18b +emXwsIwCbohSlvy7i5TQYJehy+IWRQFeD8oLkzQRtnGv+faht2xebi3i5SzJES1V +keUIgOTYIED03YpNyOWFNqBjRgiWHvfqcKOAP9CiUcsIqDNgTZoUHKcafuMDfLIc +a8hh3wsttHk21wKCAQEAgUBiaKNoLHA531wq5zGRFr8P0IAZXqxJ/RwU3VLJHFUK +Qr/hugqCFOkp3hU9H54pbZcEKHovQMYSc4sim4xnqyJB0iAV3nJl3iYBVCe9q9zv +VO97huVDH3ifIPZeN5uXYQzcOhuVfT/hRsPlpF60Ci8mV/Oqj7wYsK9q5shLBTwQ +dvE9TvupHI0571LzVhBDnY1m5s34oTARmKQjt4nbG75M/lureaZQUhnYMcWPaqMU +NDxbxdyJvLYtnnAYaWTEVd9Fb+5Elmp/p4sWoQljF+HWFVeHDaZT3Wc78Edgr49C +qqMU6AKp5yj+Hr7XOdpRF/Ly2K9MdqBt6PoqfcM+0QKCAQEAlcIQK4oZBb+cN0bt +8Q0coSCCa2IVtvDLVzFykxYK7IfxyRQB5Ck42BVjW41OZnsES7LCxU3BngAywg9T +1EBVVLyW7f//SxJYKEfNNxebHKCk+VTOmPoQDkckwGmFZM7VaSd/Tc+FdOxP7bu4 +c8fLIx7hIZUNVs0/ZHJ/ztMmc9dqfhsSPMhpTqf6w61VlCDmzxaNqwfP8VWABrjK +B5LByc6qAXIFwXJbhmGtkIhoGBdAYK3DzTweGyR2BFTI4g5BdrtarGzcwcEAVOyq +LwJYaJQYhfN/JUebpGfB/YY9t16c0+NiYqMmWZH7+aooP4fhVdFl1SCMoyRLIwG5 +vCZMrQKCAQBamPky1dKIfOehquwmcQnNZF0Wh/7tfJv2xhX6FswbPhFhAAepXmsY +4NKqqEy8pXgZ/7vXLawGAgQr2taPF4hx9QSmUNefZZpgOVVyfZgskfpMi8NcYGex +Ap4C52EiSWUooj+7vsaTvzIkUxnEUy18aRfxhTKkHcbv+d9bYOr6/BZrpetpFQEW +DzQ5dETUDhTaCyJknj3SLZRqoxOcyDkgUzFY9fJbzdlUYTtMLgnRmA37xTVuWfDR +MxLnssq56iONJylCox0sNkdhFe1f4JiLYyStHzerhCTNtSD53c6Q5hWmCFJXwllO +rdcA+RwiWNrxDmbPFs7HuiIft5MwbmdE +-----END PRIVATE KEY----- From 740cfb6b6469448d42a82de4fbc0275d8401a542 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Fri, 18 Dec 2020 09:36:06 -0800 Subject: [PATCH 011/115] Allow setting osquery environment This enables setting the enroll secret, and therefore the started osquery process can actually enroll with Fleet. --- go.mod | 1 + go.sum | 11 +++++++ main.go | 67 ++++++++++++++++++++++++------------------ src/osquery/osquery.go | 7 +++++ 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 737ca87bc2..080556e4d4 100644 --- a/go.mod +++ b/go.mod @@ -8,4 +8,5 @@ require ( github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.6.1 + github.com/urfave/cli/v2 v2.3.0 ) diff --git a/go.sum b/go.sum index 72f8244e7c..1ffaff0efc 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,8 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= @@ -13,10 +16,18 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 6bb9583290..98732ed462 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "github.com/fleetdm/orbit/src/certificate" "github.com/fleetdm/orbit/src/osquery" "github.com/oklog/run" + "github.com/urfave/cli/v2" ) const ( @@ -19,35 +20,45 @@ const ( ) func main() { - fmt.Println("Hello osquery!") + app := cli.NewApp() + app.Name = "Orbit osquery" + app.Usage = "A (near) drop-in replacement for osquery with features to ease the deployment to your Fleet." + app.Action = func(c *cli.Context) error { - osqueryPath, err := exec.LookPath("osqueryd") - if err != nil { - log.Fatalf("no osquery found: %v", err) + osqueryPath, err := exec.LookPath("osqueryd") + if err != nil { + log.Fatalf("no osquery found: %v", err) + } + + serverCert, err := certificate.FetchPEM(serverURL) + if err != nil { + log.Fatalf("retrieve server cert: %v", err) + } + err = ioutil.WriteFile(certPath, serverCert, os.ModePerm) + if err != nil { + log.Fatalf("write server cert: %v", err) + } + + ctx, cancel := context.WithCancel(context.Background()) + var g run.Group + g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) + + r, _ := osquery.NewRunner( + osquery.WithFlags(osquery.FleetFlags(serverURL)), + osquery.WithFlags([]string{"--tls_server_certs", certPath}), + osquery.WithEnv([]string{"ENROLL_SECRET=fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn"}), + osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), + ) + g.Add(r.Execute, r.Interrupt) + + err = g.Run() + fmt.Println(err) + + _, _ = osqueryPath, cancel + //cmd := exec.CommandContext() + // + return nil } - serverCert, err := certificate.FetchPEM(serverURL) - if err != nil { - log.Fatalf("retrieve server cert: %v", err) - } - err = ioutil.WriteFile(certPath, serverCert, os.ModePerm) - if err != nil { - log.Fatalf("write server cert: %v", err) - } - - ctx, cancel := context.WithCancel(context.Background()) - var g run.Group - g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) - - r, _ := osquery.NewRunner( - osquery.WithFlags(osquery.FleetFlags(serverURL)), - osquery.WithFlags([]string{"--tls_server_certs", certPath}), - ) - g.Add(r.Execute, r.Interrupt) - - err = g.Run() - fmt.Println(err) - - _, _ = osqueryPath, cancel - //cmd := exec.CommandContext() + app.Run(os.Args) } diff --git a/src/osquery/osquery.go b/src/osquery/osquery.go index ff2d2eb4ae..0d0c931451 100644 --- a/src/osquery/osquery.go +++ b/src/osquery/osquery.go @@ -52,6 +52,13 @@ func WithFlags(flags []string) func(*Runner) error { } } +func WithEnv(env []string) func(*Runner) error { + return func(r *Runner) error { + r.cmd.Env = append(r.cmd.Env, env...) + return nil + } +} + func (r *Runner) Execute() error { if err := r.proc.Start(); err != nil { return errors.Wrap(err, "start osquery") From 3be4b62d2677e8f698d191f64236f65510e40177 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Fri, 18 Dec 2020 18:29:51 -0800 Subject: [PATCH 012/115] PoC of --insecure implemented via TLS proxy By proxying osquery's TLS connection we can manage the certificate to ease testing. The strategy used is obviously insecure and must only be presented to the user in that context. --- main.go | 44 ++++++-- src/insecure/proxy.go | 212 +++++++++++++++++++++++++++++++++++++ src/insecure/proxy_test.go | 14 +++ 3 files changed, 263 insertions(+), 7 deletions(-) create mode 100644 src/insecure/proxy.go create mode 100644 src/insecure/proxy_test.go diff --git a/main.go b/main.go index 98732ed462..b1ca43e193 100644 --- a/main.go +++ b/main.go @@ -8,9 +8,10 @@ import ( "os" "os/exec" - "github.com/fleetdm/orbit/src/certificate" + "github.com/fleetdm/orbit/src/insecure" "github.com/fleetdm/orbit/src/osquery" "github.com/oklog/run" + "github.com/pkg/errors" "github.com/urfave/cli/v2" ) @@ -22,7 +23,21 @@ const ( func main() { app := cli.NewApp() app.Name = "Orbit osquery" - app.Usage = "A (near) drop-in replacement for osquery with features to ease the deployment to your Fleet." + app.Usage = "A powered-up, (near) drop-in replacement for osquery" + app.Flags = []cli.Flag{ + &cli.BoolFlag{ + Name: "insecure", + Usage: "Disable TLS certificate verification", + }, + &cli.StringFlag{ + Name: "fleet_url", + Usage: "URL (host:port) to Fleet server", + }, + &cli.StringFlag{ + Name: "enroll_secret", + Usage: "Enroll secret for authenticating to Fleet server", + }, + } app.Action = func(c *cli.Context) error { osqueryPath, err := exec.LookPath("osqueryd") @@ -30,13 +45,14 @@ func main() { log.Fatalf("no osquery found: %v", err) } - serverCert, err := certificate.FetchPEM(serverURL) + proxy, err := insecure.NewTLSProxy("localhost:8080") if err != nil { - log.Fatalf("retrieve server cert: %v", err) + return errors.Wrap(err, "create TLS proxy") } - err = ioutil.WriteFile(certPath, serverCert, os.ModePerm) + + err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) if err != nil { - log.Fatalf("write server cert: %v", err) + return errors.Wrap(err, "write server cert") } ctx, cancel := context.WithCancel(context.Background()) @@ -44,13 +60,27 @@ func main() { g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) r, _ := osquery.NewRunner( - osquery.WithFlags(osquery.FleetFlags(serverURL)), + osquery.WithFlags(osquery.FleetFlags(fmt.Sprintf("localhost:%d", proxy.Port))), osquery.WithFlags([]string{"--tls_server_certs", certPath}), + osquery.WithFlags([]string{"--verbose"}), osquery.WithEnv([]string{"ENROLL_SECRET=fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn"}), osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), ) g.Add(r.Execute, r.Interrupt) + g.Add( + func() error { + err := proxy.InsecureServeTLS() + log.Println(err) + return err + }, + func(error) { + if err := proxy.Close(); err != nil { + log.Printf("error closing proxy: %v", err) + } + }, + ) + err = g.Run() fmt.Println(err) diff --git a/src/insecure/proxy.go b/src/insecure/proxy.go new file mode 100644 index 0000000000..44aa67f4b5 --- /dev/null +++ b/src/insecure/proxy.go @@ -0,0 +1,212 @@ +// Package insecure provides an insecure (if it were not obvious yet) TLS proxy +// that can be used for testing osquery enrollment with a Fleet (or other TLS) +// server in non-production environments. +// +// Functions in this package are NOT SUITABLE FOR PRODUCTION ENVIRONMENTS! +package insecure + +import ( + "context" + "crypto/tls" + "net" + "net/http" + "net/http/httputil" + "net/url" + "strings" + "time" + + "github.com/pkg/errors" +) + +const ( + // ServerCert is the certificate used by the proxy server. + ServerCert = `-----BEGIN CERTIFICATE----- +MIICpDCCAYwCCQCPnw3uINXlozANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls +b2NhbGhvc3QwHhcNMjAxMjE5MDA0MDA0WhcNNDgwNTA1MDA0MDA0WjAUMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1 +GuqbXIo767H1dPM9KS7Uz6bU3Jzh/4e5fxmgxTz2GY76UiKhBKvlWIy2PsFMKpQ1 +kd3/MyANoOcUkdolPAX/6jMZc9qhlRaG80MqgZuBzX3KHnCnFN9vin1wOrTlyboW +NLjKCmKTCpa0knuya9hgOwCJ1cFMFByC29qRvYKtisQxRbpy/d/jN14dXsGeQiZW +KU6ncmFPBH8+uTnrQq4A3UBFMOu5C+Uk+hCSLNMu4ZbAUR41m0LpR5OaWk1t0q2O +ZbDg4zkSJzbBNeiVe+vCbKtevqtRgqAi4u4EGdasnlhEJ/UPfF9lvqCd1iRw7M9u +quPlsJs6tE4GFBpIUUMBAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA5KnpFoTnKW +B04G42v6a2AkY/ENEgoMhKr6JBeRkRKF6Itatiotb/RClgRYlDUn+ljow8/Tyds4 +qqMl/MzjbbwI4xNcu9t+0bG2zmJj6ON4mbRH+GnBPX+t50/1eKSoPjtHDyT/UAbx +q3jyXp0nObaRzDqmYK/OUVg7vhAxQqQ9Cvvk819Ar8wFZGjE9Bc2YDObyCVQWCZz +qIfzr/Qh46tq0o+KdlaV2oHy4VLrLOFXeD5MKf6A7aOP7h9Yy9ywnScrobaSXwd8 +kS/PZzVeJtwvKf+c1tBiJxHix2vLiFtS5IKdhNGKNvMyQNWgq046iTNeVJkxo+Qb +YP4a5WpD+aw= +-----END CERTIFICATE----- +` + + // serverKey is the corresponding private key. This key is compromised by + // being in the source code, rendering any connection using this cert + // insecure. + serverKey = `-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1GuqbXIo767H1 +dPM9KS7Uz6bU3Jzh/4e5fxmgxTz2GY76UiKhBKvlWIy2PsFMKpQ1kd3/MyANoOcU +kdolPAX/6jMZc9qhlRaG80MqgZuBzX3KHnCnFN9vin1wOrTlyboWNLjKCmKTCpa0 +knuya9hgOwCJ1cFMFByC29qRvYKtisQxRbpy/d/jN14dXsGeQiZWKU6ncmFPBH8+ +uTnrQq4A3UBFMOu5C+Uk+hCSLNMu4ZbAUR41m0LpR5OaWk1t0q2OZbDg4zkSJzbB +NeiVe+vCbKtevqtRgqAi4u4EGdasnlhEJ/UPfF9lvqCd1iRw7M9uquPlsJs6tE4G +FBpIUUMBAgMBAAECggEBAKUhQcEfA7vXEJBqbk7Z+iV4oPl9nl5CjBKK3WdF8GvE +qiV8Nq7yf3nC36pcVguI11JxCiXjC9rhV1HeGzXQIPhTJvySMksakUvDCv765jvY +jlV4o+b0lTYy5GUsYj0TTmVo9QTjqzW/deJ3nen1g3la0wbarEEeJVD7/bLdRQXN +9DcFtKpC+to0N7RE2cFLGIgWcU/W6IF+DoLkVKdd0h2EZ4FawRtythkfC2Z+B1W/ +ayz645XIQcA2sI2z4G2CqR/k3gmv6eGzoQgTN46z2lYqPFMD7v8hwv9Z/LCIghF9 +iJQy8Uxy8zRjmCDNP0oWRrlIUh2abqhgLlvvYsFJ3QECgYEA4Z0FJmsgf65NlBzQ +g5+x9pQLZX0tEpeuDZT+W9i+7u/d1nkISmD+urL+f1o5Jc8dg0QG9Y6XFodIsp8W +s6wbCcBR+V7q76fJONRLnh5mHNwBvvVGg5Iy/Bmc8gTboG7F4yJnrvCYeE4gIVXt +4c5c7B1hOC/eyXIGng5bbKwtCAkCgYEAzX9JSOwWlt3Y75SCL8d3WSEBVqgaH1UZ +4lSZ/Bi1F7uUToJGMnH2XinZ0tO7erPtisl/S9SZhMmIFho+p/23Mz4SWtLGzIBu +q8Zoo4gfCk2cP5YkidKad1Kc3ZG4LWQCiRr7+HYYmTXaUWe5PNznlp36IFliPlkK +Q2ztNOpq8TkCgYBa4SQ08IwbwnuPgPfhPU+zcrkQfZbNWXoMEItRNgLbPpYOkZxs +UZvqWrW3WQGSIFbUDG/9NB3aPk5jXUAIyffuOqEKoVhjhyPAF4wKOlaJo3m0kRqB +Xz/YWvzkZF6Pxm9B6hb32gSg2V+J7hIvli/KEJ+bwXStkpflzQS4xrYw+QKBgGqH +T8Bj0xoGi403WX3XU4F64KzBnDkd7rsrzF+pl0dkUG+ajTVdarBJ1ce7R3dGix/l +cP4oiiUSLF/43v5LQotn5C/9EF23PqgBxQDxcdXvgc5c0Tg5WyX8R6F9BxNQwxe8 +S170KbBTAIgu0xJAGjY0UxQuAgX8NpvZfeZul13RAoGARVSBIo5MDodDw25j4fc7 +YIC5ppouCT4VTz6IUOxYyw8TQBBm5Wes62JJ+9yTLLfIRNnkDkVwSX7Q3blva+1W +1lFBG1WzNhTRo0im9lRyVCGp2ZSm2UxsJS9jP1J6bkavkjK/jaPOC9J6dmWOZBWm +yJY8h/0WhN9XPcXFa4Qmfu0= +-----END PRIVATE KEY----- +` +) + +// TLSProxy is the insecure TLS proxy implementation. This type should only be +// initialized via NewTLSProxy. +type TLSProxy struct { + // Port is the port the TLS proxy is listening on (always on localhost). + Port int + + listener net.Listener + server *http.Server +} + +// NewTLSProxy creates a new proxy implementation targeting the provided +// hostname. +func NewTLSProxy(targetHostname string) (*TLSProxy, error) { + cert, err := tls.X509KeyPair([]byte(ServerCert), []byte(serverKey)) + if err != nil { + return nil, errors.Wrap(err, "load keypair") + } + cfg := &tls.Config{Certificates: []tls.Certificate{cert}} + + // Assign any available port + listener, err := tls.Listen("tcp", "localhost:0", cfg) + if err != nil { + return nil, errors.Wrap(err, "bind localhost") + } + + addr, ok := listener.Addr().(*net.TCPAddr) + if !ok { + return nil, errors.New("listener is not *net.TCPAddr") + } + + handler, err := newProxyHandler(targetHostname) + if err != nil { + return nil, errors.Wrap(err, "make proxy handler") + } + + proxy := &TLSProxy{ + Port: addr.Port, + listener: listener, + server: &http.Server{Handler: handler}, + } + + return proxy, nil +} + +// InsecureServeTLS will begin running the TLS proxy. +func (p *TLSProxy) InsecureServeTLS() error { + if p.listener == nil || p.server == nil { + return errors.New("listener and handler must not be nil -- initialize TLSProxy via NewTLSProxy") + } + + err := p.server.Serve(p.listener) + return errors.Wrap(err, "servetls returned") +} + +// Close the server and associated listener. The server may not be reused after +// calling Close(). +func (p *TLSProxy) Close() error { + // err := p.listener.Close() + // if err != nil { + // return errors.Wrap(err, "close listener") + // } + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + return p.server.Shutdown(ctx) +} + +func newProxyHandler(hostname string) (*httputil.ReverseProxy, error) { + target, err := url.Parse(hostname) + if err != nil { + return nil, errors.Wrap(err, "parse hostname") + } + target.Scheme = "https" + + reverseProxy := &httputil.ReverseProxy{ + Director: func(req *http.Request) { + req.Host = hostname + req.URL.Scheme = "https" + req.URL.Host = hostname + req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) + }, + } + // Adapted from http.DefaultTransport + reverseProxy.Transport = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + + return reverseProxy, nil +} + +// Copied from Go source +// https://go.googlesource.com/go/+/go1.15.6/src/net/http/httputil/reverseproxy.go#114 +func joinURLPath(a, b *url.URL) (path, rawpath string) { + if a.RawPath == "" && b.RawPath == "" { + return singleJoiningSlash(a.Path, b.Path), "" + } + // Same as singleJoiningSlash, but uses EscapedPath to determine + // whether a slash should be added + apath := a.EscapedPath() + bpath := b.EscapedPath() + aslash := strings.HasSuffix(apath, "/") + bslash := strings.HasPrefix(bpath, "/") + switch { + case aslash && bslash: + return a.Path + b.Path[1:], apath + bpath[1:] + case !aslash && !bslash: + return a.Path + "/" + b.Path, apath + "/" + bpath + } + return a.Path + b.Path, apath + bpath +} + +// Copied from Go source +// https://go.googlesource.com/go/+/go1.15.6/src/net/http/httputil/reverseproxy.go#102 +func singleJoiningSlash(a, b string) string { + aslash := strings.HasSuffix(a, "/") + bslash := strings.HasPrefix(b, "/") + switch { + case aslash && bslash: + return a + b[1:] + case !aslash && !bslash: + return a + "/" + b + } + return a + b +} diff --git a/src/insecure/proxy_test.go b/src/insecure/proxy_test.go new file mode 100644 index 0000000000..c32f1fec4f --- /dev/null +++ b/src/insecure/proxy_test.go @@ -0,0 +1,14 @@ +package insecure + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestProxy(t *testing.T) { + proxy, err := NewTLSProxy("localhost") + require.NoError(t, err) + assert.NotZero(t, proxy.Port) +} From c1265f451ea84b1403352f48009c7a72c37358da Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Fri, 18 Dec 2020 18:40:17 -0800 Subject: [PATCH 013/115] Cleanup in main function --- main.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index b1ca43e193..803e14be56 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,6 @@ import ( "io/ioutil" "log" "os" - "os/exec" "github.com/fleetdm/orbit/src/insecure" "github.com/fleetdm/orbit/src/osquery" @@ -39,13 +38,7 @@ func main() { }, } app.Action = func(c *cli.Context) error { - - osqueryPath, err := exec.LookPath("osqueryd") - if err != nil { - log.Fatalf("no osquery found: %v", err) - } - - proxy, err := insecure.NewTLSProxy("localhost:8080") + proxy, err := insecure.NewTLSProxy(serverURL) if err != nil { return errors.Wrap(err, "create TLS proxy") } @@ -55,8 +48,10 @@ func main() { return errors.Wrap(err, "write server cert") } - ctx, cancel := context.WithCancel(context.Background()) var g run.Group + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) r, _ := osquery.NewRunner( @@ -84,11 +79,10 @@ func main() { err = g.Run() fmt.Println(err) - _, _ = osqueryPath, cancel - //cmd := exec.CommandContext() - // return nil } - app.Run(os.Args) + if err := app.Run(os.Args); err != nil { + log.Println("Error:", err) + } } From f4716e0770958ac8c6ac6ecd81a0fd664b3653ec Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 21 Dec 2020 15:57:38 -0800 Subject: [PATCH 014/115] Rename src subdirectory to pkg This makes directory naming consistent with Fleet. --- main.go | 4 ++-- {src => pkg}/certificate/certificate.go | 0 {src => pkg}/certificate/certificate_test.go | 0 {src => pkg}/certificate/testdata/test.crt | 0 {src => pkg}/certificate/testdata/test.key | 0 {src => pkg}/insecure/proxy.go | 0 {src => pkg}/insecure/proxy_test.go | 0 {src => pkg}/osquery/flags.go | 0 {src => pkg}/osquery/osquery.go | 2 +- {src => pkg}/process/process.go | 0 {src => pkg}/process/process_mock.go | 0 {src => pkg}/process/process_test.go | 0 12 files changed, 3 insertions(+), 3 deletions(-) rename {src => pkg}/certificate/certificate.go (100%) rename {src => pkg}/certificate/certificate_test.go (100%) rename {src => pkg}/certificate/testdata/test.crt (100%) rename {src => pkg}/certificate/testdata/test.key (100%) rename {src => pkg}/insecure/proxy.go (100%) rename {src => pkg}/insecure/proxy_test.go (100%) rename {src => pkg}/osquery/flags.go (100%) rename {src => pkg}/osquery/osquery.go (97%) rename {src => pkg}/process/process.go (100%) rename {src => pkg}/process/process_mock.go (100%) rename {src => pkg}/process/process_test.go (100%) diff --git a/main.go b/main.go index 803e14be56..97022574a3 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,8 @@ import ( "log" "os" - "github.com/fleetdm/orbit/src/insecure" - "github.com/fleetdm/orbit/src/osquery" + "github.com/fleetdm/orbit/pkg/insecure" + "github.com/fleetdm/orbit/pkg/osquery" "github.com/oklog/run" "github.com/pkg/errors" "github.com/urfave/cli/v2" diff --git a/src/certificate/certificate.go b/pkg/certificate/certificate.go similarity index 100% rename from src/certificate/certificate.go rename to pkg/certificate/certificate.go diff --git a/src/certificate/certificate_test.go b/pkg/certificate/certificate_test.go similarity index 100% rename from src/certificate/certificate_test.go rename to pkg/certificate/certificate_test.go diff --git a/src/certificate/testdata/test.crt b/pkg/certificate/testdata/test.crt similarity index 100% rename from src/certificate/testdata/test.crt rename to pkg/certificate/testdata/test.crt diff --git a/src/certificate/testdata/test.key b/pkg/certificate/testdata/test.key similarity index 100% rename from src/certificate/testdata/test.key rename to pkg/certificate/testdata/test.key diff --git a/src/insecure/proxy.go b/pkg/insecure/proxy.go similarity index 100% rename from src/insecure/proxy.go rename to pkg/insecure/proxy.go diff --git a/src/insecure/proxy_test.go b/pkg/insecure/proxy_test.go similarity index 100% rename from src/insecure/proxy_test.go rename to pkg/insecure/proxy_test.go diff --git a/src/osquery/flags.go b/pkg/osquery/flags.go similarity index 100% rename from src/osquery/flags.go rename to pkg/osquery/flags.go diff --git a/src/osquery/osquery.go b/pkg/osquery/osquery.go similarity index 97% rename from src/osquery/osquery.go rename to pkg/osquery/osquery.go index 0d0c931451..28e26150b5 100644 --- a/src/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -7,7 +7,7 @@ import ( "os/exec" "time" - "github.com/fleetdm/orbit/src/process" + "github.com/fleetdm/orbit/pkg/process" "github.com/pkg/errors" ) diff --git a/src/process/process.go b/pkg/process/process.go similarity index 100% rename from src/process/process.go rename to pkg/process/process.go diff --git a/src/process/process_mock.go b/pkg/process/process_mock.go similarity index 100% rename from src/process/process_mock.go rename to pkg/process/process_mock.go diff --git a/src/process/process_test.go b/pkg/process/process_test.go similarity index 100% rename from src/process/process_test.go rename to pkg/process/process_test.go From 37ffb54b8615050439db5bdc137fc68b11a49f6b Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 22 Dec 2020 14:29:13 -0800 Subject: [PATCH 015/115] Connect CLI flags --- main.go | 96 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/main.go b/main.go index 97022574a3..c652d449cb 100644 --- a/main.go +++ b/main.go @@ -38,46 +38,74 @@ func main() { }, } app.Action = func(c *cli.Context) error { - proxy, err := insecure.NewTLSProxy(serverURL) - if err != nil { - return errors.Wrap(err, "create TLS proxy") - } - - err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) - if err != nil { - return errors.Wrap(err, "write server cert") - } - var g run.Group + var options []func(*osquery.Runner) error + fleetURL := c.String("fleet_url") + + if c.Bool("insecure") { + proxy, err := insecure.NewTLSProxy(fleetURL) + if err != nil { + return errors.Wrap(err, "create TLS proxy") + } + + g.Add( + func() error { + err := proxy.InsecureServeTLS() + log.Println(err) + return err + }, + func(error) { + if err := proxy.Close(); err != nil { + log.Printf("error closing proxy: %v", err) + } + }, + ) + + // Write cert that proxy uses + err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) + if err != nil { + return errors.Wrap(err, "write server cert") + } + + // Rewrite URL to the proxy URL + fleetURL = fmt.Sprintf("localhost:%d", proxy.Port) + + options = append(options, + osquery.WithFlags(osquery.FleetFlags(fleetURL)), + osquery.WithFlags([]string{"--tls_server_certs", certPath}), + ) + } + + if enrollSecret := c.String("enroll_secret"); enrollSecret != "" { + options = append(options, + osquery.WithEnv([]string{"ENROLL_SECRET="}), + osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), + ) + } + + if fleetURL != "" { + options = append(options, + osquery.WithFlags(osquery.FleetFlags(fleetURL)), + ) + } + + options = append(options, + osquery.WithFlags([]string{"--verbose"}), + ) + + // Create an osquery runner with the provided options + r, _ := osquery.NewRunner(options...) + g.Add(r.Execute, r.Interrupt) + + // Install a signal handler ctx, cancel := context.WithCancel(context.Background()) defer cancel() g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) - r, _ := osquery.NewRunner( - osquery.WithFlags(osquery.FleetFlags(fmt.Sprintf("localhost:%d", proxy.Port))), - osquery.WithFlags([]string{"--tls_server_certs", certPath}), - osquery.WithFlags([]string{"--verbose"}), - osquery.WithEnv([]string{"ENROLL_SECRET=fTp52/twaxBU6gIi0J6PHp8o5Sm1k1kn"}), - osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), - ) - g.Add(r.Execute, r.Interrupt) - - g.Add( - func() error { - err := proxy.InsecureServeTLS() - log.Println(err) - return err - }, - func(error) { - if err := proxy.Close(); err != nil { - log.Printf("error closing proxy: %v", err) - } - }, - ) - - err = g.Run() - fmt.Println(err) + if err := g.Run(); err != nil { + fmt.Println(err) + } return nil } From 0c232ed07f35ffd4fafd6fa846468d68f50d086f Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 22 Dec 2020 18:36:45 -0800 Subject: [PATCH 016/115] Add update package Initial implementation of download and hash function. --- pkg/update/update.go | 63 ++++++++++++++++++++++ pkg/update/update_test.go | 111 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 pkg/update/update.go create mode 100644 pkg/update/update_test.go diff --git a/pkg/update/update.go b/pkg/update/update.go new file mode 100644 index 0000000000..d380e9c9b0 --- /dev/null +++ b/pkg/update/update.go @@ -0,0 +1,63 @@ +// package update contains the types and functions used by the update system. +package update + +import ( + "bytes" + "crypto/sha512" + "encoding/base64" + "io" + "net/http" + + "github.com/pkg/errors" +) + +// DownloadWithSHA512Hash downloads the contents of the given URL, writing +// results to the provided writer. The size is used as an upper limit on the +// amount of data read. An error is returned if the hash of the data received +// does not match the expected hash. +func DownloadWithSHA512Hash(url string, out io.Writer, size int64, expectedHash []byte) error { + resp, err := http.Get(url) + if err != nil { + return errors.Wrap(err, "make get request") + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return errors.Errorf("unexpected HTTP status: %s", resp.Status) + } + + hash := sha512.New() + + // Limit size of response read to expected size + limitReader := &io.LimitedReader{ + R: resp.Body, + N: size + 1, + } + + // Tee the bytes through the hash function + teeReader := io.TeeReader(limitReader, hash) + + n, err := io.Copy(out, teeReader) + if err != nil { + return errors.Wrap(err, "copy response body") + } + // Technically these cases would be caught by the hash, but these errors are + // hopefully a bit more helpful. + if n < size { + return errors.New("response smaller than expected") + } + if n > size { + return errors.New("response larger than expected") + } + + // Validate the hash matches + gotHash := hash.Sum(nil) + if bytes.Compare(gotHash, expectedHash) != 0 { + return errors.Errorf( + "hash %s does not match expected %s", + base64.StdEncoding.EncodeToString(gotHash), + base64.StdEncoding.EncodeToString(expectedHash), + ) + } + + return nil +} diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go new file mode 100644 index 0000000000..94a5204abf --- /dev/null +++ b/pkg/update/update_test.go @@ -0,0 +1,111 @@ +package update + +import ( + "bytes" + "crypto/sha512" + "fmt" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDownloadWithSHA512HashInvalidURL(t *testing.T) { + t.Parallel() + + err := DownloadWithSHA512Hash("localhost:12345569900", ioutil.Discard, 55, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "make get request") +} + +func TestDownloadWithSHA512HashErrorResponse(t *testing.T) { + t.Parallel() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "error", http.StatusInternalServerError) + })) + defer ts.Close() + + err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, 55, nil) + require.Error(t, err) + assert.Contains(t, err.Error(), "unexpected HTTP status") +} + +func TestDownloadWithSHA512Hash(t *testing.T) { + t.Parallel() + + expectedData := []byte("abc") + expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, string(expectedData)) + })) + defer ts.Close() + + var b bytes.Buffer + err := DownloadWithSHA512Hash(ts.URL, &b, expectedLen, expectedHash) + require.NoError(t, err) + assert.Equal(t, expectedData, b.Bytes()) +} + +func TestDownloadWithSHA512HashTooSmall(t *testing.T) { + t.Parallel() + + expectedData := []byte("abc") + expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Don't write all of data + fmt.Fprintf(w, string(expectedData[:2])) + })) + defer ts.Close() + + err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) + require.Error(t, err) + assert.Contains(t, err.Error(), "small") +} + +func TestDownloadWithSHA512HashTooLarge(t *testing.T) { + t.Parallel() + + expectedData := []byte("abc") + expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Write additional data + fmt.Fprintf(w, string(expectedData)+"foobar") + })) + defer ts.Close() + + err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) + require.Error(t, err) + assert.Contains(t, err.Error(), "large") +} + +func TestDownloadWithSHA512HashMismatch(t *testing.T) { + t.Parallel() + + expectedData := []byte("abc") + expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Write non-matching data + fmt.Fprintf(w, string("def")) + })) + defer ts.Close() + + err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) + require.Error(t, err) + assert.Contains(t, err.Error(), "not match") +} + +func sha512Hash(data []byte) []byte { + hash := sha512.New() + if _, err := hash.Write(data); err != nil { + panic(err) + } + return hash.Sum(nil) +} From a69feb558d075a7b4670e7b01b6df61d3c2629e0 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 23 Dec 2020 08:32:06 -0800 Subject: [PATCH 017/115] Fix lint --- pkg/update/update.go | 2 +- pkg/update/update_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/update/update.go b/pkg/update/update.go index d380e9c9b0..5f5c6bcbce 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -51,7 +51,7 @@ func DownloadWithSHA512Hash(url string, out io.Writer, size int64, expectedHash // Validate the hash matches gotHash := hash.Sum(nil) - if bytes.Compare(gotHash, expectedHash) != 0 { + if !bytes.Equal(gotHash, expectedHash) { return errors.Errorf( "hash %s does not match expected %s", base64.StdEncoding.EncodeToString(gotHash), diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index 94a5204abf..75ed1cca3c 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -41,7 +41,7 @@ func TestDownloadWithSHA512Hash(t *testing.T) { expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, string(expectedData)) + fmt.Fprint(w, string(expectedData)) })) defer ts.Close() @@ -59,7 +59,7 @@ func TestDownloadWithSHA512HashTooSmall(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Don't write all of data - fmt.Fprintf(w, string(expectedData[:2])) + fmt.Fprint(w, string(expectedData[:2])) })) defer ts.Close() @@ -93,7 +93,7 @@ func TestDownloadWithSHA512HashMismatch(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Write non-matching data - fmt.Fprintf(w, string("def")) + fmt.Fprint(w, string("def")) })) defer ts.Close() From 4f43b9266aaa43e57ba98fd2df8f06f824e9e1e7 Mon Sep 17 00:00:00 2001 From: Zachary Wasserman Date: Wed, 23 Dec 2020 16:51:47 -0800 Subject: [PATCH 018/115] Add initial directory handling --- main.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index c652d449cb..98393d4dab 100644 --- a/main.go +++ b/main.go @@ -23,21 +23,32 @@ func main() { app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" + defaultRootDir := "/usr/local/orbit" app.Flags = []cli.Flag{ + &cli.StringFlag{ + Name: "root-dir", + Usage: "Root directory for Orbit state", + Value: defaultRootDir, + }, &cli.BoolFlag{ Name: "insecure", Usage: "Disable TLS certificate verification", }, &cli.StringFlag{ - Name: "fleet_url", + Name: "fleet-url", Usage: "URL (host:port) to Fleet server", }, &cli.StringFlag{ - Name: "enroll_secret", + Name: "enroll-secret", Usage: "Enroll secret for authenticating to Fleet server", }, } app.Action = func(c *cli.Context) error { + err := initialize(c) + if err != nil { + return errors.Wrap(err, "initialize") + } + var g run.Group var options []func(*osquery.Runner) error @@ -114,3 +125,13 @@ func main() { log.Println("Error:", err) } } + +func initialize(c *cli.Context) error { + fmt.Println(c.String("root-dir")) + err := os.MkdirAll(c.String("root-dir"), 0o600) + if err != nil { + return errors.Wrap(err, "make root directory") + } + + return nil +} From 0101ef839b91454a267903cd16f8b75633306013 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 23 Dec 2020 19:20:31 -0800 Subject: [PATCH 019/115] Add constant package Currently only file and directory mode defaults. --- go.mod | 4 ++ go.sum | 113 +++++++++++++++++++++++++++++++++++++++ main.go | 50 ++++++++++++++++- pkg/constant/constant.go | 8 +++ 4 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 pkg/constant/constant.go diff --git a/go.mod b/go.mod index 080556e4d4..56e0d5bbf0 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,13 @@ go 1.15 require ( github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 + github.com/docker/distribution v2.7.1+incompatible // indirect github.com/kr/pretty v0.2.1 // indirect github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 + github.com/sirupsen/logrus v1.7.0 // indirect github.com/stretchr/testify v1.6.1 + github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f github.com/urfave/cli/v2 v2.3.0 + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect ) diff --git a/go.sum b/go.sum index 1ffaff0efc..908d1221b1 100644 --- a/go.sum +++ b/go.sum @@ -1,33 +1,146 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 h1:iPf1jQ8yKTms6k6L5vYSE7RZJpjEe5vLTOmzRZdpnKc= +github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/go v1.5.1-1 h1:hr4w35acWBPhGBXlzPoHpmZ/ygPjnmFVxGxxGnMyP7k= +github.com/docker/go v1.5.1-1/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= +github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= +github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= +github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0= +github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY= +github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f h1:myKguilK7Xy8V5sjfJ8CYn2cD/aRlDFO4hzkqZ9HhgQ= +github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f/go.mod h1:VmySTua0RaZOe78Zx4/i3bCl9eNs0UvBOPV+1ps9t6U= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 98393d4dab..bdf0786d0b 100644 --- a/main.go +++ b/main.go @@ -2,15 +2,21 @@ package main import ( "context" + "crypto/tls" + "encoding/hex" "fmt" "io/ioutil" "log" + "net/http" "os" "github.com/fleetdm/orbit/pkg/insecure" "github.com/fleetdm/orbit/pkg/osquery" "github.com/oklog/run" "github.com/pkg/errors" + "github.com/theupdateframework/notary/client" + "github.com/theupdateframework/notary/trustpinning" + "github.com/theupdateframework/notary/tuf/data" "github.com/urfave/cli/v2" ) @@ -35,8 +41,9 @@ func main() { Usage: "Disable TLS certificate verification", }, &cli.StringFlag{ - Name: "fleet-url", - Usage: "URL (host:port) to Fleet server", + Name: "fleet_url", + Usage: "URL (host:port) to Fleet server", + Value: serverURL, }, &cli.StringFlag{ Name: "enroll-secret", @@ -49,6 +56,45 @@ func main() { return errors.Wrap(err, "initialize") } + rootDir := ".trust" + if err := os.MkdirAll(rootDir, 0700); err != nil { + panic(err) + } + + server := "https://localhost:4443" + image := "example.com/collection" + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: true, + } + repo, err := client.NewFileCachedRepository( + rootDir, + data.GUN(image), + server, + transport, + nil, + trustpinning.TrustPinConfig{}, + ) + if err != nil { + panic(err) + } + + targets, err := repo.ListTargets() + if err != nil { + panic(err) + } + + for _, tgt := range targets { + fmt.Printf("%s\t%s\n", tgt.Name, hex.EncodeToString(tgt.Hashes["sha256"])) + } + + tgt, err := repo.GetTargetByName("LICENSE") + if err != nil { + panic(err) + } + fmt.Printf("%+v\n", tgt) +>>>>>>> Stashed changes + var g run.Group var options []func(*osquery.Runner) error diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go new file mode 100644 index 0000000000..60060e3308 --- /dev/null +++ b/pkg/constant/constant.go @@ -0,0 +1,8 @@ +package constant + +const ( + // DefaultDirMode is the default file mode to apply to created directories. + DefaultDirMode = 0o700 + // DefaultFileMode is the default file mode to apply to created files. + DefaultFileMode = 0o600 +) From 9d4af7f3266704ccb4a437d7a361df4666d7d69f Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 11 Jan 2021 16:38:53 -0800 Subject: [PATCH 020/115] Checkpoint Notary update changes --- main.go | 114 +++++++++++++++++++++----------------- pkg/update/update.go | 97 ++++++++++++++++++++++++++++++++ pkg/update/update_test.go | 23 ++++++++ 3 files changed, 183 insertions(+), 51 deletions(-) diff --git a/main.go b/main.go index bdf0786d0b..ce6b91ed8d 100644 --- a/main.go +++ b/main.go @@ -2,26 +2,23 @@ package main import ( "context" - "crypto/tls" - "encoding/hex" "fmt" "io/ioutil" "log" - "net/http" "os" + "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/insecure" "github.com/fleetdm/orbit/pkg/osquery" + "github.com/fleetdm/orbit/pkg/update" "github.com/oklog/run" "github.com/pkg/errors" - "github.com/theupdateframework/notary/client" - "github.com/theupdateframework/notary/trustpinning" - "github.com/theupdateframework/notary/tuf/data" "github.com/urfave/cli/v2" ) const ( serverURL = "localhost:8080" + notaryURL = "https://localhost:4443" certPath = "/tmp/fleet.pem" ) @@ -41,64 +38,79 @@ func main() { Usage: "Disable TLS certificate verification", }, &cli.StringFlag{ - Name: "fleet_url", - Usage: "URL (host:port) to Fleet server", + Name: "fleet-url", + Usage: "URL (host:port) to Fleet server", Value: serverURL, }, + &cli.StringFlag{ + Name: "notary-url", + Usage: "URL (host:port) to Notary update server", + Value: notaryURL, + }, &cli.StringFlag{ Name: "enroll-secret", Usage: "Enroll secret for authenticating to Fleet server", }, } app.Action = func(c *cli.Context) error { - err := initialize(c) + // err := initialize(c) + // if err != nil { + // return errors.Wrap(err, "initialize") + // } + + // rootDir := ".trust" + // if err := os.MkdirAll(rootDir, 0700); err != nil { + // panic(err) + // } + + // server := "https://localhost:4443" + // image := "example.com/collection" + // transport := http.DefaultTransport.(*http.Transport).Clone() + // transport.TLSClientConfig = &tls.Config{ + // InsecureSkipVerify: true, + // } + // repo, err := client.NewFileCachedRepository( + // rootDir, + // data.GUN(image), + // server, + // transport, + // nil, + // trustpinning.TrustPinConfig{}, + // ) + // if err != nil { + // panic(err) + // } + + // targets, err := repo.ListTargets() + // if err != nil { + // panic(err) + // } + + // for _, tgt := range targets { + // fmt.Printf("%s\t%s\n", tgt.Name, hex.EncodeToString(tgt.Hashes["sha256"])) + // } + + // tgt, err := repo.GetTargetByName("LICENSE") + // if err != nil { + // panic(err) + // } + // fmt.Printf("%+v\n", tgt) + + updater, err := update.New(update.Options{ + RootDirectory: c.String("root-dir"), + ServerURL: c.String("notary-url"), + InsecureTransport: true, + }) if err != nil { - return errors.Wrap(err, "initialize") + return err } - - rootDir := ".trust" - if err := os.MkdirAll(rootDir, 0700); err != nil { - panic(err) - } - - server := "https://localhost:4443" - image := "example.com/collection" - transport := http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: true, - } - repo, err := client.NewFileCachedRepository( - rootDir, - data.GUN(image), - server, - transport, - nil, - trustpinning.TrustPinConfig{}, - ) - if err != nil { - panic(err) - } - - targets, err := repo.ListTargets() - if err != nil { - panic(err) - } - - for _, tgt := range targets { - fmt.Printf("%s\t%s\n", tgt.Name, hex.EncodeToString(tgt.Hashes["sha256"])) - } - - tgt, err := repo.GetTargetByName("LICENSE") - if err != nil { - panic(err) - } - fmt.Printf("%+v\n", tgt) ->>>>>>> Stashed changes + fmt.Println(updater.Lookup("test", "LICENSE")) + _ = updater var g run.Group var options []func(*osquery.Runner) error - fleetURL := c.String("fleet_url") + fleetURL := c.String("fleet-url") if c.Bool("insecure") { proxy, err := insecure.NewTLSProxy(fleetURL) @@ -174,7 +186,7 @@ func main() { func initialize(c *cli.Context) error { fmt.Println(c.String("root-dir")) - err := os.MkdirAll(c.String("root-dir"), 0o600) + err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode) if err != nil { return errors.Wrap(err, "make root directory") } diff --git a/pkg/update/update.go b/pkg/update/update.go index 5f5c6bcbce..0513ff624e 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -4,13 +4,110 @@ package update import ( "bytes" "crypto/sha512" + "crypto/tls" "encoding/base64" "io" "net/http" + "os" + "path/filepath" + "github.com/fleetdm/orbit/pkg/constant" "github.com/pkg/errors" + "github.com/theupdateframework/notary/client" + "github.com/theupdateframework/notary/trustpinning" + "github.com/theupdateframework/notary/tuf/data" ) +const ( + binDir = "bin" + osqueryDir = "osquery" + orbitDir = "orbit" + + notaryDir = "notary" +) + +// Updater is responsible for managing update state. +type Updater struct { + opt Options + transport *http.Transport +} + +// Options are the options that can be provided when creating an Updater. +type Options struct { + // RootDirectory is the root directory from which other directories should be referenced. + RootDirectory string + // ServerURL is the URL of the update server. + ServerURL string + // GUN is the Globally Unique Name to look up with the Notary server. + GUN string + // InsecureTransport skips TLS certificate verification in the transport if + // set to true. + InsecureTransport bool +} + +// New creates a new updater given the provided options. All the necessary +// directories are initialized. +func New(opt Options) (*Updater, error) { + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: opt.InsecureTransport, + } + + updater := &Updater{ + opt: opt, + transport: transport, + } + + err := updater.initializeDirectories() + if err != nil { + return nil, err + } + + return updater, nil +} + +// Lookup returns the target metadata for the provided GUN and target name. +func (u *Updater) Lookup(GUN, target string) (*client.Target, error) { + client, err := client.NewFileCachedRepository( + u.pathFromRoot(notaryDir), + data.GUN(GUN), + u.opt.ServerURL, + u.transport, + nil, + trustpinning.TrustPinConfig{}, + ) + if err != nil { + return nil, errors.Wrap(err, "make notary client") + } + + targetWithRole, err := client.GetTargetByName(target) + if err != nil { + return nil, errors.Wrap(err, "get target by name") + } + + return &targetWithRole.Target, nil +} + +func (u *Updater) pathFromRoot(parts ...string) string { + return filepath.Join(append([]string{u.opt.RootDirectory}, parts...)...) +} + +func (u *Updater) initializeDirectories() error { + for _, dir := range []string{ + u.pathFromRoot(binDir), + u.pathFromRoot(binDir, osqueryDir), + u.pathFromRoot(binDir, orbitDir), + u.pathFromRoot(notaryDir), + } { + err := os.MkdirAll(dir, constant.DefaultDirMode) + if err != nil { + return errors.Wrap(err, "initialize directories") + } + } + + return nil +} + // DownloadWithSHA512Hash downloads the contents of the given URL, writing // results to the provided writer. The size is used as an upper limit on the // amount of data read. An error is returned if the hash of the data received diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index 75ed1cca3c..c7f8175bda 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -7,6 +7,8 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -109,3 +111,24 @@ func sha512Hash(data []byte) []byte { } return hash.Sum(nil) } + +func TestInitializeDirectories(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "orbit-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + _, err = New(Options{RootDirectory: tmpDir}) + require.NoError(t, err) + assertDir(t, filepath.Join(tmpDir, binDir)) + assertDir(t, filepath.Join(tmpDir, binDir, osqueryDir)) + assertDir(t, filepath.Join(tmpDir, binDir, orbitDir)) + assertDir(t, filepath.Join(tmpDir, notaryDir)) +} + +func assertDir(t *testing.T, path string) { + info, err := os.Stat(path) + assert.NoError(t, err, "stat should succeed") + assert.True(t, info.IsDir()) +} From 0af9b67d892baa95b786d37f3d87ca28003d9052 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 12 Jan 2021 18:58:33 -0800 Subject: [PATCH 021/115] Add initial Badger database implementation Code for opening and managing the Badger database. --- pkg/database/database.go | 77 +++++++++++++++++++++++++++++++++ pkg/database/database_test.go | 80 +++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 pkg/database/database.go create mode 100644 pkg/database/database_test.go diff --git a/pkg/database/database.go b/pkg/database/database.go new file mode 100644 index 0000000000..0f736382d7 --- /dev/null +++ b/pkg/database/database.go @@ -0,0 +1,77 @@ +package database + +import ( + "log" + "time" + + "github.com/dgraph-io/badger/v2" + "github.com/pkg/errors" +) + +const ( + compactionInterval = 5 * time.Minute + // This is the discard ratio recommended in Badger docs + // (https://pkg.go.dev/github.com/dgraph-io/badger#DB.RunValueLogGC) + compactionDiscardRatio = 0.5 +) + +// BadgerDB is a wrapper around the standard badger.DB that provides a +// background compaction routine. +type BadgerDB struct { + *badger.DB + closeChan chan struct{} +} + +// Open opens (initializing if necessary) a new Badger database at the specified +// path. Users must close the DB with Close(). +func Open(path string) (*BadgerDB, error) { + // DefaultOptions sets synchronous writes to true (maximum data integrity). + // TODO implement logging? + db, err := badger.Open(badger.DefaultOptions(path).WithLogger(nil)) + if err != nil { + return nil, errors.Wrapf(err, "open badger %s", path) + } + + b := &BadgerDB{DB: db} + b.startBackgroundCompaction() + + return b, nil +} + +// startBackgroundCompaction starts a background loop that will call the +// compaction method on the database. Badger does not do this automatically, so +// we need to be sure to do so here (or elsewhere). +func (b *BadgerDB) startBackgroundCompaction() { + if b.closeChan != nil { + panic("background compaction already running") + } + b.closeChan = make(chan struct{}) + + go func() { + ticker := time.NewTicker(compactionInterval) + defer ticker.Stop() + for { + select { + case <-b.closeChan: + return + + case <-ticker.C: + if err := b.DB.RunValueLogGC(compactionDiscardRatio); err != nil { + log.Printf("Error compacting Badger: %v", err) + } + } + } + }() +} + +// stopBackgroundCompaction stops the background compaction routine. +func (b *BadgerDB) stopBackgroundCompaction() { + b.closeChan <- struct{}{} + b.closeChan = nil +} + +// Close closes the database connection and releases the associated resources. +func (b *BadgerDB) Close() error { + b.stopBackgroundCompaction() + return b.DB.Close() +} diff --git a/pkg/database/database_test.go b/pkg/database/database_test.go new file mode 100644 index 0000000000..22414665bf --- /dev/null +++ b/pkg/database/database_test.go @@ -0,0 +1,80 @@ +package database + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/dgraph-io/badger/v2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestDatabase(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "orbit-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + // Open and write + db, err := Open(tmpDir) + require.NoError(t, err) + + err = db.Update(func(tx *badger.Txn) error { + require.NoError(t, tx.Set([]byte("key"), []byte("value"))) + return nil + }) + require.NoError(t, err) + require.NoError(t, db.Close()) + + // Reopen and read + db, err = Open(tmpDir) + require.NoError(t, err) + + err = db.View(func(tx *badger.Txn) error { + item, err := tx.Get([]byte("key")) + require.NoError(t, err) + err = item.Value(func(val []byte) error { + assert.Equal(t, []byte("value"), val) + return nil + }) + require.NoError(t, err) + + return nil + }) + require.NoError(t, err) + require.NoError(t, db.Close()) +} + +func TestCompactionPanic(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "orbit-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + db, err := Open(tmpDir) + require.NoError(t, err) + + // Try to start the compaction routine again + assert.Panics(t, func() { db.startBackgroundCompaction() }) +} + +func TestCompactionRestart(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "orbit-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + db, err := Open(tmpDir) + require.NoError(t, err) + go func() { + require.NoError(t, db.Close()) + }() + + db.stopBackgroundCompaction() + + assert.NotPanics(t, func() { db.startBackgroundCompaction() }) +} From 501e404f5e5f0d48ef92b7923f8d2e1dab038dc2 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 12 Jan 2021 19:00:16 -0800 Subject: [PATCH 022/115] Add PoC autoupdate functionality This demonstrates the ability to download the verified "stable" version of osquery and execute it with the given flags. --- go.mod | 11 +- go.sum | 141 ++++++------- main.go | 89 ++++----- pkg/certificate/certificate_test.go | 2 +- pkg/constant/constant.go | 3 + pkg/osquery/osquery.go | 12 +- pkg/update/badgerstore/badgerstore.go | 69 +++++++ pkg/update/badgerstore/badgerstore_test.go | 31 +++ pkg/update/file.go | 16 ++ pkg/update/hash.go | 52 +++++ pkg/update/update.go | 220 +++++++++++++-------- pkg/update/update_test.go | 130 +++--------- 12 files changed, 450 insertions(+), 326 deletions(-) create mode 100644 pkg/update/badgerstore/badgerstore.go create mode 100644 pkg/update/badgerstore/badgerstore_test.go create mode 100644 pkg/update/file.go create mode 100644 pkg/update/hash.go diff --git a/go.mod b/go.mod index 56e0d5bbf0..729dad12f4 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,15 @@ module github.com/fleetdm/orbit go 1.15 require ( - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 - github.com/docker/distribution v2.7.1+incompatible // indirect - github.com/kr/pretty v0.2.1 // indirect + github.com/dgraph-io/badger/v2 v2.2007.2 + github.com/golang/protobuf v1.3.4 // indirect + github.com/kr/text v0.2.0 // indirect github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.7.0 // indirect + github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.6.1 - github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f + github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 github.com/urfave/cli/v2 v2.3.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect + golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e // indirect ) diff --git a/go.sum b/go.sum index 908d1221b1..ae24fb8f0a 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/agl/ed25519 v0.0.0-20200225211852-fd4d107ace12 h1:iPf1jQ8yKTms6k6L5vYSE7RZJpjEe5vLTOmzRZdpnKc= -github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= +github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= +github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -17,130 +18,110 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/go v1.5.1-1 h1:hr4w35acWBPhGBXlzPoHpmZ/ygPjnmFVxGxxGnMyP7k= -github.com/docker/go v1.5.1-1/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= -github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= -github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= +github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= +github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= -github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= -github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/theupdateframework/notary v0.6.1 h1:7wshjstgS9x9F5LuB1L5mBI2xNMObWqjz+cjWoom6l0= -github.com/theupdateframework/notary v0.6.1/go.mod h1:MOfgIfmox8s7/7fduvB2xyPPMJCrjRLRizA8OFwpnKY= -github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f h1:myKguilK7Xy8V5sjfJ8CYn2cD/aRlDFO4hzkqZ9HhgQ= -github.com/theupdateframework/notary v0.6.2-0.20200804143915-84287fd8df4f/go.mod h1:VmySTua0RaZOe78Zx4/i3bCl9eNs0UvBOPV+1ps9t6U= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 h1:iGnD/q9160NWqKZZ5vY4p0dMiYMRknzctfSkqA4nBDw= +github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug= +github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 h1:Zn+mA4qTRyao2Petd+YovKaFOUuxDj158kqCIqvwTow= +github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= -gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index ce6b91ed8d..8f9a926852 100644 --- a/main.go +++ b/main.go @@ -6,11 +6,14 @@ import ( "io/ioutil" "log" "os" + "path/filepath" "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/database" "github.com/fleetdm/orbit/pkg/insecure" "github.com/fleetdm/orbit/pkg/osquery" "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/badgerstore" "github.com/oklog/run" "github.com/pkg/errors" "github.com/urfave/cli/v2" @@ -18,7 +21,7 @@ import ( const ( serverURL = "localhost:8080" - notaryURL = "https://localhost:4443" + notaryURL = "https://tuf.fleetctl.com" certPath = "/tmp/fleet.pem" ) @@ -26,7 +29,7 @@ func main() { app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" - defaultRootDir := "/usr/local/orbit" + defaultRootDir := "/usr/local/fleet" app.Flags = []cli.Flag{ &cli.StringFlag{ Name: "root-dir", @@ -53,59 +56,37 @@ func main() { }, } app.Action = func(c *cli.Context) error { - // err := initialize(c) - // if err != nil { - // return errors.Wrap(err, "initialize") - // } + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize root dir") + } - // rootDir := ".trust" - // if err := os.MkdirAll(rootDir, 0700); err != nil { - // panic(err) - // } - - // server := "https://localhost:4443" - // image := "example.com/collection" - // transport := http.DefaultTransport.(*http.Transport).Clone() - // transport.TLSClientConfig = &tls.Config{ - // InsecureSkipVerify: true, - // } - // repo, err := client.NewFileCachedRepository( - // rootDir, - // data.GUN(image), - // server, - // transport, - // nil, - // trustpinning.TrustPinConfig{}, - // ) - // if err != nil { - // panic(err) - // } - - // targets, err := repo.ListTargets() - // if err != nil { - // panic(err) - // } - - // for _, tgt := range targets { - // fmt.Printf("%s\t%s\n", tgt.Name, hex.EncodeToString(tgt.Hashes["sha256"])) - // } - - // tgt, err := repo.GetTargetByName("LICENSE") - // if err != nil { - // panic(err) - // } - // fmt.Printf("%+v\n", tgt) - - updater, err := update.New(update.Options{ - RootDirectory: c.String("root-dir"), - ServerURL: c.String("notary-url"), - InsecureTransport: true, - }) + db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) + if err != nil { + return err + } + defer func() { + if err := db.Close(); err != nil { + log.Printf("Error closing badger: %v", err) + } + }() + + opt := update.DefaultOptions + opt.RootDirectory = c.String("root-dir") + opt.ServerURL = c.String("notary-url") + opt.LocalStore = badgerstore.New(db.DB) + updater, err := update.New(opt) + if err != nil { + return err + } + if err := updater.UpdateMetadata(); err != nil { + return err + } + log.Println(updater.Targets()) + + osquerydPath, err := updater.Get("osqueryd", "macos", "stable") if err != nil { return err } - fmt.Println(updater.Lookup("test", "LICENSE")) - _ = updater var g run.Group var options []func(*osquery.Runner) error @@ -146,9 +127,9 @@ func main() { ) } - if enrollSecret := c.String("enroll_secret"); enrollSecret != "" { + if enrollSecret := c.String("enroll-secret"); enrollSecret != "" { options = append(options, - osquery.WithEnv([]string{"ENROLL_SECRET="}), + osquery.WithEnv([]string{"ENROLL_SECRET=" + enrollSecret}), osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), ) } @@ -163,6 +144,8 @@ func main() { osquery.WithFlags([]string{"--verbose"}), ) + options = append(options, osquery.WithPath(osquerydPath)) + // Create an osquery runner with the provided options r, _ := osquery.NewRunner(options...) g.Add(r.Execute, r.Interrupt) diff --git a/pkg/certificate/certificate_test.go b/pkg/certificate/certificate_test.go index 66fe400d74..13104a4e31 100644 --- a/pkg/certificate/certificate_test.go +++ b/pkg/certificate/certificate_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/bmizerany/assert" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go index 60060e3308..ce7ed7692b 100644 --- a/pkg/constant/constant.go +++ b/pkg/constant/constant.go @@ -5,4 +5,7 @@ const ( DefaultDirMode = 0o700 // DefaultFileMode is the default file mode to apply to created files. DefaultFileMode = 0o600 + // DefaultExecutableMode is the default file mode to apply to created + // executable files. + DefaultExecutableMode = 0o700 ) diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 28e26150b5..f5a34bde98 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -59,13 +59,21 @@ func WithEnv(env []string) func(*Runner) error { } } +func WithPath(path string) func(*Runner) error { + return func(r *Runner) error { + r.cmd.Path = path + return nil + } +} + func (r *Runner) Execute() error { + ctx, cancel := context.WithCancel(context.Background()) + r.cancel = cancel + if err := r.proc.Start(); err != nil { return errors.Wrap(err, "start osquery") } - ctx, cancel := context.WithCancel(context.Background()) - r.cancel = cancel if err := r.proc.StopOrKill(ctx, 10*time.Second); err != nil { return errors.Wrap(err, "osquery exited with error") } diff --git a/pkg/update/badgerstore/badgerstore.go b/pkg/update/badgerstore/badgerstore.go new file mode 100644 index 0000000000..cbb97d94ea --- /dev/null +++ b/pkg/update/badgerstore/badgerstore.go @@ -0,0 +1,69 @@ +// package badgerstore implements the go-tuf LocalStore interface using Badger +// as a backing store. +package badgerstore + +import ( + "encoding/json" + "strings" + + "github.com/dgraph-io/badger/v2" + "github.com/theupdateframework/go-tuf/client" +) + +const ( + keyPrefix = ":tuf-metadata:" +) + +type badgerStore struct { + db *badger.DB +} + +// New creates the new store given the badger DB instance. +func New(db *badger.DB) client.LocalStore { + return &badgerStore{db: db} +} + +// SetMeta stores the provided metadata. +func (b *badgerStore) SetMeta(name string, meta json.RawMessage) error { + if err := b.db.Update(func(tx *badger.Txn) error { + if err := tx.Set([]byte(keyPrefix+name), meta); err != nil { + return err + } + return nil + }); err != nil { + return err + } + + return nil +} + +// GetMeta returns all of the saved metadata. +func (b *badgerStore) GetMeta() (map[string]json.RawMessage, error) { + res := make(map[string]json.RawMessage) + + // Iterate all keys with matching prefix + // Adapted from Badger docs + if err := b.db.View(func(txn *badger.Txn) error { + it := txn.NewIterator(badger.DefaultIteratorOptions) + defer it.Close() + prefix := []byte(keyPrefix) + for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() { + item := it.Item() + k := item.Key() + + if err := item.Value(func(v []byte) error { + // Remember to strip prefix + strippedKey := strings.TrimPrefix(string(k), keyPrefix) + res[strippedKey] = json.RawMessage(v) + return nil + }); err != nil { + return err + } + } + return nil + }); err != nil { + return res, err + } + + return res, nil +} diff --git a/pkg/update/badgerstore/badgerstore_test.go b/pkg/update/badgerstore/badgerstore_test.go new file mode 100644 index 0000000000..56fab9f72f --- /dev/null +++ b/pkg/update/badgerstore/badgerstore_test.go @@ -0,0 +1,31 @@ +package badgerstore + +import ( + "encoding/json" + "testing" + + "github.com/dgraph-io/badger/v2" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBadgerStore(t *testing.T) { + badgerClient, err := badger.Open(badger.DefaultOptions("").WithInMemory(true)) + require.NoError(t, err) + + store := New(badgerClient) + + expected := map[string]json.RawMessage{ + "test": json.RawMessage("json"), + "test2": json.RawMessage("json2"), + "root.json": json.RawMessage(`[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"0994148e5242118d1d6a9a397a3646e0423545a37794a791c28aa39de3b0c523"}}]`), + } + + for k, v := range expected { + require.NoError(t, store.SetMeta(k, v)) + } + + res, err := store.GetMeta() + require.NoError(t, err) + assert.Equal(t, expected, res) +} diff --git a/pkg/update/file.go b/pkg/update/file.go new file mode 100644 index 0000000000..696a55318e --- /dev/null +++ b/pkg/update/file.go @@ -0,0 +1,16 @@ +package update + +import "os" + +// fileDestination wraps the standard os.File with a Delete method for +// compatibility with the go-tuf Destination interface. +// Adapted from +// https://github.com/theupdateframework/go-tuf/blob/master/cmd/tuf-client/get.go +type fileDestination struct { + *os.File +} + +func (f *fileDestination) Delete() error { + _ = f.Close() + return os.Remove(f.Name()) +} diff --git a/pkg/update/hash.go b/pkg/update/hash.go new file mode 100644 index 0000000000..cd7fc69648 --- /dev/null +++ b/pkg/update/hash.go @@ -0,0 +1,52 @@ +package update + +import ( + "bytes" + "crypto/sha256" + "crypto/sha512" + "hash" + "io" + "os" + + "github.com/pkg/errors" + "github.com/theupdateframework/go-tuf/data" +) + +// CheckFileHash checks the file at the local path against the provided hash +// functions. +func CheckFileHash(meta *data.TargetFileMeta, localPath string) error { + hashFunc, hashVal, err := selectHashFunction(meta) + if err != nil { + return err + } + + f, err := os.Open(localPath) + if err != nil { + return errors.Wrap(err, "open file for hash") + } + + if _, err := io.Copy(hashFunc, f); err != nil { + return errors.Wrap(err, "read file for hash") + } + + if !bytes.Equal(hashVal, hashFunc.Sum(nil)) { + return errors.Errorf("hash %s does not match expected: %s", data.HexBytes(hashFunc.Sum(nil)), data.HexBytes(hashVal)) + } + + return nil +} + +// selectHashFunction returns the first matching hash function and expected +// hash, otherwise returning an error if not matching hash can be found. +func selectHashFunction(meta *data.TargetFileMeta) (hash.Hash, []byte, error) { + for hashName, hashVal := range meta.Hashes { + switch hashName { + case "sha512": + return sha512.New(), hashVal, nil + case "sha256": + return sha256.New(), hashVal, nil + } + } + + return nil, nil, errors.Errorf("no matching hash function found: %v", meta.HashAlgorithms()) +} diff --git a/pkg/update/update.go b/pkg/update/update.go index 0513ff624e..979a91b767 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -2,20 +2,19 @@ package update import ( - "bytes" - "crypto/sha512" "crypto/tls" - "encoding/base64" - "io" + "encoding/json" + "io/ioutil" + "log" "net/http" "os" + "path" "path/filepath" "github.com/fleetdm/orbit/pkg/constant" "github.com/pkg/errors" - "github.com/theupdateframework/notary/client" - "github.com/theupdateframework/notary/trustpinning" - "github.com/theupdateframework/notary/tuf/data" + "github.com/theupdateframework/go-tuf/client" + "github.com/theupdateframework/go-tuf/data" ) const ( @@ -23,13 +22,14 @@ const ( osqueryDir = "osquery" orbitDir = "orbit" - notaryDir = "notary" + windowsExtension = ".exe" ) // Updater is responsible for managing update state. type Updater struct { opt Options transport *http.Transport + client *client.Client } // Options are the options that can be provided when creating an Updater. @@ -38,13 +38,27 @@ type Options struct { RootDirectory string // ServerURL is the URL of the update server. ServerURL string - // GUN is the Globally Unique Name to look up with the Notary server. - GUN string // InsecureTransport skips TLS certificate verification in the transport if // set to true. InsecureTransport bool + // RootKeys is the JSON encoded root keys to use to bootstrap trust. + RootKeys string + // LocalStore is the local metadata store. + LocalStore client.LocalStore } +var ( + // DefaultOptions are the default options to use when creating an update + // client. + DefaultOptions = Options{ + RootDirectory: "/var/fleet", + ServerURL: "https://tuf.fleetctl.com", + LocalStore: client.MemoryLocalStore(), + InsecureTransport: false, + RootKeys: `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"0994148e5242118d1d6a9a397a3646e0423545a37794a791c28aa39de3b0c523"}}]`, + } +) + // New creates a new updater given the provided options. All the necessary // directories are initialized. func New(opt Options) (*Updater, error) { @@ -52,40 +66,136 @@ func New(opt Options) (*Updater, error) { transport.TLSClientConfig = &tls.Config{ InsecureSkipVerify: opt.InsecureTransport, } + httpClient := &http.Client{Transport: transport} - updater := &Updater{ - opt: opt, - transport: transport, + remoteStore, err := client.HTTPRemoteStore(opt.ServerURL, nil, httpClient) + if err != nil { + return nil, errors.Wrap(err, "init remote store") } - err := updater.initializeDirectories() - if err != nil { + tufClient := client.NewClient(opt.LocalStore, remoteStore) + var rootKeys []*data.Key + if err := json.Unmarshal([]byte(opt.RootKeys), &rootKeys); err != nil { + return nil, errors.Wrap(err, "unmarshal root keys") + } + if err := tufClient.Init(rootKeys, 1); err != nil { + return nil, errors.Wrap(err, "init tuf client") + } + + updater := &Updater{ + opt: opt, + client: tufClient, + } + + if err := updater.initializeDirectories(); err != nil { return nil, err } return updater, nil } -// Lookup returns the target metadata for the provided GUN and target name. -func (u *Updater) Lookup(GUN, target string) (*client.Target, error) { - client, err := client.NewFileCachedRepository( - u.pathFromRoot(notaryDir), - data.GUN(GUN), - u.opt.ServerURL, - u.transport, - nil, - trustpinning.TrustPinConfig{}, - ) +func (u *Updater) UpdateMetadata() error { + if _, err := u.client.Update(); err != nil && errors.Is(err, &client.ErrLatestSnapshot{}) { + return errors.Wrap(err, "update metadata") + } + return nil +} + +func makeRepoPath(name, platform, version string) string { + path := path.Join(name, platform, version, name) + if platform == "windows" { + path += windowsExtension + } + return path +} + +func makeLocalPath(name, platform, version string) string { + path := filepath.Join(name, version, name) + if platform == "windows" { + path += windowsExtension + } + return path +} + +// Lookup looks up the provided target in the local target metadata. This should +// be called after UpdateMetadata. +func (u *Updater) Lookup(name, platform, version string) (*data.TargetFileMeta, error) { + target, err := u.client.Target(makeRepoPath(name, platform, version)) if err != nil { - return nil, errors.Wrap(err, "make notary client") + return nil, errors.Wrapf(err, "lookup target %s", target) } - targetWithRole, err := client.GetTargetByName(target) + return &target, nil +} + +// Targets gets all of the known targets +func (u *Updater) Targets() (data.TargetFiles, error) { + targets, err := u.client.Targets() if err != nil { - return nil, errors.Wrap(err, "get target by name") + return nil, errors.Wrapf(err, "get targets") } - return &targetWithRole.Target, nil + return targets, nil +} + +// Get returns the local path to the specified target. The target is downloaded +// if it does not yet exist locally or the hash does not match. +func (u *Updater) Get(name, platform, version string) (string, error) { + localPath := u.pathFromRoot(makeLocalPath(name, platform, version)) + repoPath := makeRepoPath(name, platform, version) + stat, err := os.Stat(localPath) + if err != nil { + log.Println("error stat file:", err) + return localPath, u.Download(repoPath, localPath) + } + if !stat.Mode().IsRegular() { + return "", errors.Errorf("expected %s to be regular file", localPath) + } + + meta, err := u.Lookup(name, platform, version) + if err != nil { + return "", err + } + + if err := CheckFileHash(meta, localPath); err != nil { + log.Printf("Will redownload due to error checking hash: %v", err) + return localPath, u.Download(repoPath, localPath) + } + + log.Printf("Found expected version locally: %s", localPath) + + return localPath, nil +} + +// Download downloads the target to the provided path. The file is deleted and +// an error is returned if the hash does not match. +func (u *Updater) Download(repoPath, localPath string) error { + tmp, err := ioutil.TempFile("", "orbit-download") + if err != nil { + return errors.Wrap(err, "open temp file for download") + } + defer func() { + tmp.Close() + os.Remove(tmp.Name()) + }() + + if err := os.MkdirAll(filepath.Dir(localPath), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize download dir") + } + + if err := u.client.Download(repoPath, &fileDestination{tmp}); err != nil { + return errors.Wrapf(err, "download target %s", repoPath) + } + + if err := os.Chmod(tmp.Name(), constant.DefaultExecutableMode); err != nil { + return errors.Wrap(err, "chmod download") + } + + if err := os.Rename(tmp.Name(), localPath); err != nil { + return errors.Wrap(err, "move download") + } + + return nil } func (u *Updater) pathFromRoot(parts ...string) string { @@ -97,7 +207,6 @@ func (u *Updater) initializeDirectories() error { u.pathFromRoot(binDir), u.pathFromRoot(binDir, osqueryDir), u.pathFromRoot(binDir, orbitDir), - u.pathFromRoot(notaryDir), } { err := os.MkdirAll(dir, constant.DefaultDirMode) if err != nil { @@ -107,54 +216,3 @@ func (u *Updater) initializeDirectories() error { return nil } - -// DownloadWithSHA512Hash downloads the contents of the given URL, writing -// results to the provided writer. The size is used as an upper limit on the -// amount of data read. An error is returned if the hash of the data received -// does not match the expected hash. -func DownloadWithSHA512Hash(url string, out io.Writer, size int64, expectedHash []byte) error { - resp, err := http.Get(url) - if err != nil { - return errors.Wrap(err, "make get request") - } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return errors.Errorf("unexpected HTTP status: %s", resp.Status) - } - - hash := sha512.New() - - // Limit size of response read to expected size - limitReader := &io.LimitedReader{ - R: resp.Body, - N: size + 1, - } - - // Tee the bytes through the hash function - teeReader := io.TeeReader(limitReader, hash) - - n, err := io.Copy(out, teeReader) - if err != nil { - return errors.Wrap(err, "copy response body") - } - // Technically these cases would be caught by the hash, but these errors are - // hopefully a bit more helpful. - if n < size { - return errors.New("response smaller than expected") - } - if n > size { - return errors.New("response larger than expected") - } - - // Validate the hash matches - gotHash := hash.Sum(nil) - if !bytes.Equal(gotHash, expectedHash) { - return errors.Errorf( - "hash %s does not match expected %s", - base64.StdEncoding.EncodeToString(gotHash), - base64.StdEncoding.EncodeToString(expectedHash), - ) - } - - return nil -} diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index c7f8175bda..84f148480d 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -1,12 +1,7 @@ package update import ( - "bytes" - "crypto/sha512" - "fmt" "io/ioutil" - "net/http" - "net/http/httptest" "os" "path/filepath" "testing" @@ -15,103 +10,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestDownloadWithSHA512HashInvalidURL(t *testing.T) { - t.Parallel() - - err := DownloadWithSHA512Hash("localhost:12345569900", ioutil.Discard, 55, nil) - require.Error(t, err) - assert.Contains(t, err.Error(), "make get request") -} - -func TestDownloadWithSHA512HashErrorResponse(t *testing.T) { - t.Parallel() - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - http.Error(w, "error", http.StatusInternalServerError) - })) - defer ts.Close() - - err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, 55, nil) - require.Error(t, err) - assert.Contains(t, err.Error(), "unexpected HTTP status") -} - -func TestDownloadWithSHA512Hash(t *testing.T) { - t.Parallel() - - expectedData := []byte("abc") - expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, string(expectedData)) - })) - defer ts.Close() - - var b bytes.Buffer - err := DownloadWithSHA512Hash(ts.URL, &b, expectedLen, expectedHash) - require.NoError(t, err) - assert.Equal(t, expectedData, b.Bytes()) -} - -func TestDownloadWithSHA512HashTooSmall(t *testing.T) { - t.Parallel() - - expectedData := []byte("abc") - expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Don't write all of data - fmt.Fprint(w, string(expectedData[:2])) - })) - defer ts.Close() - - err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) - require.Error(t, err) - assert.Contains(t, err.Error(), "small") -} - -func TestDownloadWithSHA512HashTooLarge(t *testing.T) { - t.Parallel() - - expectedData := []byte("abc") - expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Write additional data - fmt.Fprintf(w, string(expectedData)+"foobar") - })) - defer ts.Close() - - err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) - require.Error(t, err) - assert.Contains(t, err.Error(), "large") -} - -func TestDownloadWithSHA512HashMismatch(t *testing.T) { - t.Parallel() - - expectedData := []byte("abc") - expectedHash, expectedLen := sha512Hash(expectedData), int64(len(expectedData)) - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // Write non-matching data - fmt.Fprint(w, string("def")) - })) - defer ts.Close() - - err := DownloadWithSHA512Hash(ts.URL, ioutil.Discard, expectedLen, expectedHash) - require.Error(t, err) - assert.Contains(t, err.Error(), "not match") -} - -func sha512Hash(data []byte) []byte { - hash := sha512.New() - if _, err := hash.Write(data); err != nil { - panic(err) - } - return hash.Sum(nil) -} - func TestInitializeDirectories(t *testing.T) { t.Parallel() @@ -119,12 +17,14 @@ func TestInitializeDirectories(t *testing.T) { require.NoError(t, err) defer os.RemoveAll(tmpDir) - _, err = New(Options{RootDirectory: tmpDir}) + opt := DefaultOptions + opt.RootDirectory = tmpDir + updater := Updater{opt: opt} + err = updater.initializeDirectories() require.NoError(t, err) assertDir(t, filepath.Join(tmpDir, binDir)) assertDir(t, filepath.Join(tmpDir, binDir, osqueryDir)) assertDir(t, filepath.Join(tmpDir, binDir, orbitDir)) - assertDir(t, filepath.Join(tmpDir, notaryDir)) } func assertDir(t *testing.T, path string) { @@ -132,3 +32,25 @@ func assertDir(t *testing.T, path string) { assert.NoError(t, err, "stat should succeed") assert.True(t, info.IsDir()) } + +func TestMakePath(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + platform string + version string + expected string + }{ + {name: "osqueryd", platform: "linux", version: "4.6.0", expected: "osqueryd/linux/4.6.0/osqueryd"}, + {name: "osqueryd", platform: "windows", version: "3.3.2", expected: "osqueryd/windows/3.3.2/osqueryd.exe"}, + } + + for _, tt := range testCases { + t.Run(tt.expected, func(t *testing.T) { + t.Parallel() + + assert.Equal(t, tt.expected, makePath(tt.name, tt.platform, tt.version)) + }) + } +} From 45978084da513bd98decefdf0109c026b4d56885 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 12 Jan 2021 19:04:05 -0800 Subject: [PATCH 023/115] Add .gitignore --- .gitignore | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..155860f1fb --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.DS_Store +.idea +*.log +tmp/ + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out From 36478cd96c29562e68ebb6e8f4de74c138574d3d Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 12 Jan 2021 19:07:59 -0800 Subject: [PATCH 024/115] Fix lint and tests --- main.go | 10 ---------- pkg/update/update.go | 7 +++---- pkg/update/update_test.go | 4 ++-- 3 files changed, 5 insertions(+), 16 deletions(-) diff --git a/main.go b/main.go index 8f9a926852..fc93740ea8 100644 --- a/main.go +++ b/main.go @@ -166,13 +166,3 @@ func main() { log.Println("Error:", err) } } - -func initialize(c *cli.Context) error { - fmt.Println(c.String("root-dir")) - err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode) - if err != nil { - return errors.Wrap(err, "make root directory") - } - - return nil -} diff --git a/pkg/update/update.go b/pkg/update/update.go index 979a91b767..8aeb836aad 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -27,9 +27,8 @@ const ( // Updater is responsible for managing update state. type Updater struct { - opt Options - transport *http.Transport - client *client.Client + opt Options + client *client.Client } // Options are the options that can be provided when creating an Updater. @@ -122,7 +121,7 @@ func makeLocalPath(name, platform, version string) string { func (u *Updater) Lookup(name, platform, version string) (*data.TargetFileMeta, error) { target, err := u.client.Target(makeRepoPath(name, platform, version)) if err != nil { - return nil, errors.Wrapf(err, "lookup target %s", target) + return nil, errors.Wrapf(err, "lookup target %v", target) } return &target, nil diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index 84f148480d..3a5333a969 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -33,7 +33,7 @@ func assertDir(t *testing.T, path string) { assert.True(t, info.IsDir()) } -func TestMakePath(t *testing.T) { +func TestMakeRepoPath(t *testing.T) { t.Parallel() testCases := []struct { @@ -50,7 +50,7 @@ func TestMakePath(t *testing.T) { t.Run(tt.expected, func(t *testing.T) { t.Parallel() - assert.Equal(t, tt.expected, makePath(tt.name, tt.platform, tt.version)) + assert.Equal(t, tt.expected, makeRepoPath(tt.name, tt.platform, tt.version)) }) } } From 037452aba11a5a948adcf1c93f88650fa713240d Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 13 Jan 2021 17:00:46 -0800 Subject: [PATCH 025/115] Add shell subcommand --- main.go | 71 +++++++++++++++++++++++++++++--- pkg/constant/constant_darwin.go | 6 +++ pkg/constant/constant_linux.go | 6 +++ pkg/constant/constant_windows.go | 6 +++ pkg/osquery/osquery.go | 13 ++++++ pkg/update/update.go | 12 +----- 6 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 pkg/constant/constant_darwin.go create mode 100644 pkg/constant/constant_linux.go create mode 100644 pkg/constant/constant_windows.go diff --git a/main.go b/main.go index fc93740ea8..b15f3aed24 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,6 @@ import ( ) const ( - serverURL = "localhost:8080" notaryURL = "https://tuf.fleetctl.com" certPath = "/tmp/fleet.pem" ) @@ -30,6 +29,9 @@ func main() { app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" defaultRootDir := "/usr/local/fleet" + app.Commands = []*cli.Command{ + shellCommand, + } app.Flags = []cli.Flag{ &cli.StringFlag{ Name: "root-dir", @@ -43,11 +45,10 @@ func main() { &cli.StringFlag{ Name: "fleet-url", Usage: "URL (host:port) to Fleet server", - Value: serverURL, }, &cli.StringFlag{ Name: "notary-url", - Usage: "URL (host:port) to Notary update server", + Usage: "URL to Notary update server", Value: notaryURL, }, &cli.StringFlag{ @@ -70,6 +71,7 @@ func main() { } }() + // Initialize updater and get expected version opt := update.DefaultOptions opt.RootDirectory = c.String("root-dir") opt.ServerURL = c.String("notary-url") @@ -81,9 +83,7 @@ func main() { if err := updater.UpdateMetadata(); err != nil { return err } - log.Println(updater.Targets()) - - osquerydPath, err := updater.Get("osqueryd", "macos", "stable") + osquerydPath, err := updater.Get("osqueryd", constant.PlatformName, "stable") if err != nil { return err } @@ -145,6 +145,7 @@ func main() { ) options = append(options, osquery.WithPath(osquerydPath)) + options = append(options, osquery.WithShell()) // Create an osquery runner with the provided options r, _ := osquery.NewRunner(options...) @@ -166,3 +167,61 @@ func main() { log.Println("Error:", err) } } + +var shellCommand = &cli.Command{ + Name: "shell", + Aliases: []string{"osqueryi"}, + Usage: "Run the osqueryi shell", + Action: func(c *cli.Context) error { + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize root dir") + } + + db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) + if err != nil { + return err + } + defer func() { + if err := db.Close(); err != nil { + log.Printf("Error closing badger: %v", err) + } + }() + + // Initialize updater and get expected version + opt := update.DefaultOptions + opt.RootDirectory = c.String("root-dir") + opt.ServerURL = c.String("notary-url") + opt.LocalStore = badgerstore.New(db.DB) + updater, err := update.New(opt) + if err != nil { + return err + } + if err := updater.UpdateMetadata(); err != nil { + return err + } + osquerydPath, err := updater.Get("osqueryd", constant.PlatformName, "stable") + if err != nil { + return err + } + + var g run.Group + + // Create an osquery runner with the provided options + r, _ := osquery.NewRunner( + osquery.WithShell(), + osquery.WithPath(osquerydPath), + ) + g.Add(r.Execute, r.Interrupt) + + // Install a signal handler + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) + + if err := g.Run(); err != nil { + fmt.Println(err) + } + + return nil + }, +} diff --git a/pkg/constant/constant_darwin.go b/pkg/constant/constant_darwin.go new file mode 100644 index 0000000000..9a9845a243 --- /dev/null +++ b/pkg/constant/constant_darwin.go @@ -0,0 +1,6 @@ +package constant + +const ( + PlatformName = "macos" + ExecutableExtension = "" +) diff --git a/pkg/constant/constant_linux.go b/pkg/constant/constant_linux.go new file mode 100644 index 0000000000..5ce35bd0da --- /dev/null +++ b/pkg/constant/constant_linux.go @@ -0,0 +1,6 @@ +package constant + +const ( + PlatformName = "linux" + ExecutableExtension = "" +) diff --git a/pkg/constant/constant_windows.go b/pkg/constant/constant_windows.go new file mode 100644 index 0000000000..6601de54a0 --- /dev/null +++ b/pkg/constant/constant_windows.go @@ -0,0 +1,6 @@ +package constant + +const ( + PlatformName = "windows" + ExecutableExtension = ".exe" +) diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index f5a34bde98..2ebd4b47fa 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -2,6 +2,7 @@ package osquery import ( "context" + "fmt" "log" "os" "os/exec" @@ -66,7 +67,19 @@ func WithPath(path string) func(*Runner) error { } } +// WithShell adds the -S flag to run an osqueryi shell. +func WithShell() func(*Runner) error { + return func(r *Runner) error { + r.cmd.Args = append(r.cmd.Args, "-S") + r.cmd.Stdout = os.Stdout + r.cmd.Stderr = os.Stderr + r.cmd.Stdin = os.Stdin + return nil + } +} + func (r *Runner) Execute() error { + fmt.Println(r.cmd) ctx, cancel := context.WithCancel(context.Background()) r.cancel = cancel diff --git a/pkg/update/update.go b/pkg/update/update.go index 8aeb836aad..4eab87cd77 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -21,8 +21,6 @@ const ( binDir = "bin" osqueryDir = "osquery" orbitDir = "orbit" - - windowsExtension = ".exe" ) // Updater is responsible for managing update state. @@ -101,18 +99,12 @@ func (u *Updater) UpdateMetadata() error { } func makeRepoPath(name, platform, version string) string { - path := path.Join(name, platform, version, name) - if platform == "windows" { - path += windowsExtension - } + path := path.Join(name, platform, version, name+constant.ExecutableExtension) return path } func makeLocalPath(name, platform, version string) string { - path := filepath.Join(name, version, name) - if platform == "windows" { - path += windowsExtension - } + path := filepath.Join(name, version, name+constant.ExecutableExtension) return path } From 632216dc9356534d1f6720bd3bdf4e964895b3a1 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 13 Jan 2021 17:19:51 -0800 Subject: [PATCH 026/115] Make osquery version configurable at runtime --- main.go | 24 ++++++++++++++++++++++-- pkg/osquery/osquery.go | 2 -- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index b15f3aed24..ba9921500a 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,11 @@ func main() { Name: "enroll-secret", Usage: "Enroll secret for authenticating to Fleet server", }, + &cli.StringFlag{ + Name: "osqueryd-version", + Usage: "Version of osqueryd to use", + Value: "stable", + }, } app.Action = func(c *cli.Context) error { if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { @@ -83,7 +88,11 @@ func main() { if err := updater.UpdateMetadata(); err != nil { return err } - osquerydPath, err := updater.Get("osqueryd", constant.PlatformName, "stable") + osquerydPath, err := updater.Get( + "osqueryd", + constant.PlatformName, + c.String("osqueryd-version"), + ) if err != nil { return err } @@ -172,6 +181,13 @@ var shellCommand = &cli.Command{ Name: "shell", Aliases: []string{"osqueryi"}, Usage: "Run the osqueryi shell", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "osqueryd-version", + Usage: "Version of osqueryd to use", + Value: "stable", + }, + }, Action: func(c *cli.Context) error { if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "initialize root dir") @@ -199,7 +215,11 @@ var shellCommand = &cli.Command{ if err := updater.UpdateMetadata(); err != nil { return err } - osquerydPath, err := updater.Get("osqueryd", constant.PlatformName, "stable") + osquerydPath, err := updater.Get( + "osqueryd", + constant.PlatformName, + c.String("osqueryd-version"), + ) if err != nil { return err } diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 2ebd4b47fa..746949a756 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -2,7 +2,6 @@ package osquery import ( "context" - "fmt" "log" "os" "os/exec" @@ -79,7 +78,6 @@ func WithShell() func(*Runner) error { } func (r *Runner) Execute() error { - fmt.Println(r.cmd) ctx, cancel := context.WithCancel(context.Background()) r.cancel = cancel From f379b05f2d75927d1b8ad2e216795d1817b672ef Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 13 Jan 2021 18:21:25 -0800 Subject: [PATCH 027/115] Refactor logging to use zerolog --- go.mod | 1 + go.sum | 7 +++++++ main.go | 33 +++++++++++++++++++++++++++------ pkg/database/database.go | 6 +++--- pkg/osquery/osquery.go | 6 ++++-- pkg/update/update.go | 8 ++++---- 6 files changed, 46 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 729dad12f4..9c51eabeff 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 + github.com/rs/zerolog v1.20.0 github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.6.1 github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 diff --git a/go.sum b/go.sum index ae24fb8f0a..8e881d361c 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,7 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= @@ -60,6 +61,9 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= +github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= @@ -103,6 +107,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -114,6 +119,8 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwg golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= diff --git a/main.go b/main.go index ba9921500a..dcb8cfff0c 100644 --- a/main.go +++ b/main.go @@ -4,9 +4,9 @@ import ( "context" "fmt" "io/ioutil" - "log" "os" "path/filepath" + "time" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" @@ -16,6 +16,8 @@ import ( "github.com/fleetdm/orbit/pkg/update/badgerstore" "github.com/oklog/run" "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" ) @@ -25,6 +27,7 @@ const ( ) func main() { + app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" @@ -60,8 +63,17 @@ func main() { Usage: "Version of osqueryd to use", Value: "stable", }, + &cli.BoolFlag{ + Name: "debug", + Usage: "Enable debug logging", + }, } app.Action = func(c *cli.Context) error { + zerolog.SetGlobalLevel(zerolog.InfoLevel) + if c.Bool("debug") { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "initialize root dir") } @@ -72,7 +84,7 @@ func main() { } defer func() { if err := db.Close(); err != nil { - log.Printf("Error closing badger: %v", err) + log.Error().Err(err).Msg("Close badger") } }() @@ -111,12 +123,11 @@ func main() { g.Add( func() error { err := proxy.InsecureServeTLS() - log.Println(err) return err }, func(error) { if err := proxy.Close(); err != nil { - log.Printf("error closing proxy: %v", err) + log.Error().Err(err).Msg("close proxy") } }, ) @@ -173,7 +184,7 @@ func main() { } if err := app.Run(os.Args); err != nil { - log.Println("Error:", err) + log.Error().Err(err).Msg("") } } @@ -187,8 +198,18 @@ var shellCommand = &cli.Command{ Usage: "Version of osqueryd to use", Value: "stable", }, + &cli.BoolFlag{ + Name: "debug", + Usage: "Enable debug logging", + }, }, Action: func(c *cli.Context) error { + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}) + zerolog.SetGlobalLevel(zerolog.InfoLevel) + if c.Bool("debug") { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "initialize root dir") } @@ -199,7 +220,7 @@ var shellCommand = &cli.Command{ } defer func() { if err := db.Close(); err != nil { - log.Printf("Error closing badger: %v", err) + log.Error().Err(err).Msg("Close badger") } }() diff --git a/pkg/database/database.go b/pkg/database/database.go index 0f736382d7..100377348d 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -1,11 +1,11 @@ package database import ( - "log" "time" "github.com/dgraph-io/badger/v2" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) const ( @@ -56,8 +56,8 @@ func (b *BadgerDB) startBackgroundCompaction() { return case <-ticker.C: - if err := b.DB.RunValueLogGC(compactionDiscardRatio); err != nil { - log.Printf("Error compacting Badger: %v", err) + if err := b.DB.RunValueLogGC(compactionDiscardRatio); err != nil && !errors.Is(err, badger.ErrNoRewrite) { + log.Error().Err(err).Msg("compact badger") } } } diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 746949a756..3c912bda6c 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -2,13 +2,13 @@ package osquery import ( "context" - "log" "os" "os/exec" "time" "github.com/fleetdm/orbit/pkg/process" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) type Runner struct { @@ -78,6 +78,8 @@ func WithShell() func(*Runner) error { } func (r *Runner) Execute() error { + log.Debug().Str("cmd", r.cmd.String()).Msg("Run osquery") + ctx, cancel := context.WithCancel(context.Background()) r.cancel = cancel @@ -93,6 +95,6 @@ func (r *Runner) Execute() error { } func (r *Runner) Interrupt(err error) { - log.Printf("interrupt osquery") + log.Debug().Msg("interrupt osquery") r.cancel() } diff --git a/pkg/update/update.go b/pkg/update/update.go index 4eab87cd77..afc2001dd0 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "encoding/json" "io/ioutil" - "log" "net/http" "os" "path" @@ -13,6 +12,7 @@ import ( "github.com/fleetdm/orbit/pkg/constant" "github.com/pkg/errors" + "github.com/rs/zerolog/log" "github.com/theupdateframework/go-tuf/client" "github.com/theupdateframework/go-tuf/data" ) @@ -136,7 +136,7 @@ func (u *Updater) Get(name, platform, version string) (string, error) { repoPath := makeRepoPath(name, platform, version) stat, err := os.Stat(localPath) if err != nil { - log.Println("error stat file:", err) + log.Debug().Err(err).Msg("stat file") return localPath, u.Download(repoPath, localPath) } if !stat.Mode().IsRegular() { @@ -149,11 +149,11 @@ func (u *Updater) Get(name, platform, version string) (string, error) { } if err := CheckFileHash(meta, localPath); err != nil { - log.Printf("Will redownload due to error checking hash: %v", err) + log.Debug().Err(err).Msg("will redownload due to error checking hash") return localPath, u.Download(repoPath, localPath) } - log.Printf("Found expected version locally: %s", localPath) + log.Debug().Str("path", localPath).Msg("found expected version locally") return localPath, nil } From b82bb7000856bb66a3627ba3730a5e54cff99294 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 14 Jan 2021 09:40:33 -0800 Subject: [PATCH 028/115] Allow passing args through to osquery with -- --- main.go | 8 +++++--- pkg/osquery/osquery.go | 10 +++++----- pkg/process/process.go | 2 +- pkg/process/process_test.go | 22 +++++++++++----------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/main.go b/main.go index dcb8cfff0c..ec0f44dae4 100644 --- a/main.go +++ b/main.go @@ -166,6 +166,7 @@ func main() { options = append(options, osquery.WithPath(osquerydPath)) options = append(options, osquery.WithShell()) + options = append(options, osquery.WithFlags([]string(c.Args().Slice()))) // Create an osquery runner with the provided options r, _ := osquery.NewRunner(options...) @@ -177,7 +178,7 @@ func main() { g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) if err := g.Run(); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("unexpected exit") } return nil @@ -220,7 +221,7 @@ var shellCommand = &cli.Command{ } defer func() { if err := db.Close(); err != nil { - log.Error().Err(err).Msg("Close badger") + log.Error().Err(err).Msg("close badger") } }() @@ -251,6 +252,7 @@ var shellCommand = &cli.Command{ r, _ := osquery.NewRunner( osquery.WithShell(), osquery.WithPath(osquerydPath), + osquery.WithFlags([]string(c.Args().Slice())), ) g.Add(r.Execute, r.Interrupt) @@ -260,7 +262,7 @@ var shellCommand = &cli.Command{ g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) if err := g.Run(); err != nil { - fmt.Println(err) + log.Error().Err(err).Msg("unexpected exit") } return nil diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 3c912bda6c..070bc45615 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -78,20 +78,20 @@ func WithShell() func(*Runner) error { } func (r *Runner) Execute() error { - log.Debug().Str("cmd", r.cmd.String()).Msg("Run osquery") + log.Debug().Str("cmd", r.cmd.String()).Msg("run osqueryd") ctx, cancel := context.WithCancel(context.Background()) r.cancel = cancel if err := r.proc.Start(); err != nil { - return errors.Wrap(err, "start osquery") + return errors.Wrap(err, "start osqueryd") } - if err := r.proc.StopOrKill(ctx, 10*time.Second); err != nil { - return errors.Wrap(err, "osquery exited with error") + if err := r.proc.WaitOrKill(ctx, 10*time.Second); err != nil { + return errors.Wrap(err, "osqueryd exited with error") } - return errors.New("osquery exited unexpectedly") + return nil } func (r *Runner) Interrupt(err error) { diff --git a/pkg/process/process.go b/pkg/process/process.go index db77ae44d2..0cd1e33785 100644 --- a/pkg/process/process.go +++ b/pkg/process/process.go @@ -48,7 +48,7 @@ func newWithMock(cmd ExecCmd) *Process { // // Adapted from Go core: // https://github.com/golang/go/blob/8981092d71aee273d27b0e11cf932a34d4d365c1/src/cmd/go/script_test.go#L1131-L1190 -func (p *Process) StopOrKill(ctx context.Context, killDelay time.Duration) error { +func (p *Process) WaitOrKill(ctx context.Context, killDelay time.Duration) error { if p.OsProcess() == nil { return fmt.Errorf("WaitOrKill requires a non-nil OsProcess - missing Start call?") } diff --git a/pkg/process/process_test.go b/pkg/process/process_test.go index 8282de64ff..6028445022 100644 --- a/pkg/process/process_test.go +++ b/pkg/process/process_test.go @@ -18,12 +18,12 @@ func TestWaitOrKillNilProcess(t *testing.T) { mockCmd.On("OsProcess").Return(nil) p := newWithMock(mockCmd) - err := p.StopOrKill(context.Background(), 1*time.Second) + err := p.WaitOrKill(context.Background(), 1*time.Second) require.Error(t, err) assert.Contains(t, err.Error(), "non-nil OsProcess") } -func TestStopOrKillProcessCompleted(t *testing.T) { +func TestWaitOrKillProcessCompleted(t *testing.T) { // Process already completed mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -32,11 +32,11 @@ func TestStopOrKillProcessCompleted(t *testing.T) { mockCmd.On("Wait").Return(nil) p := newWithMock(mockCmd) - err := p.StopOrKill(context.Background(), 10*time.Millisecond) + err := p.WaitOrKill(context.Background(), 10*time.Millisecond) require.NoError(t, err) } -func TestStopOrKillProcessCompletedError(t *testing.T) { +func TestWaitOrKillProcessCompletedError(t *testing.T) { // Process already completed with error mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -45,12 +45,12 @@ func TestStopOrKillProcessCompletedError(t *testing.T) { mockCmd.On("Wait").After(10 * time.Millisecond).Return(fmt.Errorf("super bad")) p := newWithMock(mockCmd) - err := p.StopOrKill(context.Background(), 10*time.Millisecond) + err := p.WaitOrKill(context.Background(), 10*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "super bad") } -func TestStopOrKillWait(t *testing.T) { +func TestWaitOrKillWait(t *testing.T) { // Process completes after the wait call and after the signal is sent mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -62,12 +62,12 @@ func TestStopOrKillWait(t *testing.T) { p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.StopOrKill(ctx, 10*time.Millisecond) + err := p.WaitOrKill(ctx, 10*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "context canceled") } -func TestStopOrKillWaitSignalCompleted(t *testing.T) { +func TestWaitOrKillWaitSignalCompleted(t *testing.T) { // Process completes after the wait call and before the signal is sent mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -79,11 +79,11 @@ func TestStopOrKillWaitSignalCompleted(t *testing.T) { p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.StopOrKill(ctx, 5*time.Millisecond) + err := p.WaitOrKill(ctx, 5*time.Millisecond) require.NoError(t, err) } -func TestStopOrKillWaitKilled(t *testing.T) { +func TestWaitOrKillWaitKilled(t *testing.T) { // Process is killed after the wait call and signal mockCmd := &mockExecCmd{} mockProcess := &mockOsProcess{} @@ -96,7 +96,7 @@ func TestStopOrKillWaitKilled(t *testing.T) { p := newWithMock(mockCmd) ctx, cancel := context.WithCancel(context.Background()) cancel() - err := p.StopOrKill(ctx, 5*time.Millisecond) + err := p.WaitOrKill(ctx, 5*time.Millisecond) require.Error(t, err) assert.Contains(t, err.Error(), "context canceled") } From fdf0e75d04e2f2209faf866064d29a94ebb9a610 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 14 Jan 2021 18:31:02 -0800 Subject: [PATCH 029/115] Refactoring and cleanup --- main.go | 34 ++++++++++++++-------------------- pkg/osquery/flags.go | 1 + pkg/osquery/osquery.go | 12 ++++++++++++ pkg/update/update.go | 28 ++++++++++++++++------------ pkg/update/update_test.go | 27 +++++++++++++++++++++------ 5 files changed, 64 insertions(+), 38 deletions(-) diff --git a/main.go b/main.go index ec0f44dae4..572dd2e602 100644 --- a/main.go +++ b/main.go @@ -22,12 +22,11 @@ import ( ) const ( - notaryURL = "https://tuf.fleetctl.com" - certPath = "/tmp/fleet.pem" + tufURL = "https://tuf.fleetctl.com" + certPath = "/tmp/fleet.pem" ) func main() { - app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" @@ -50,9 +49,9 @@ func main() { Usage: "URL (host:port) to Fleet server", }, &cli.StringFlag{ - Name: "notary-url", - Usage: "URL to Notary update server", - Value: notaryURL, + Name: "tuf-url", + Usage: "URL to TUF update server", + Value: tufURL, }, &cli.StringFlag{ Name: "enroll-secret", @@ -90,8 +89,8 @@ func main() { // Initialize updater and get expected version opt := update.DefaultOptions - opt.RootDirectory = c.String("root-dir") - opt.ServerURL = c.String("notary-url") + opt.RootDirectory = c.String("tuf-dir") + opt.ServerURL = c.String("tuf-url") opt.LocalStore = badgerstore.New(db.DB) updater, err := update.New(opt) if err != nil { @@ -100,11 +99,7 @@ func main() { if err := updater.UpdateMetadata(); err != nil { return err } - osquerydPath, err := updater.Get( - "osqueryd", - constant.PlatformName, - c.String("osqueryd-version"), - ) + osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) if err != nil { return err } @@ -205,7 +200,9 @@ var shellCommand = &cli.Command{ }, }, Action: func(c *cli.Context) error { - log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}) + log.Logger = log.Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, + ) zerolog.SetGlobalLevel(zerolog.InfoLevel) if c.Bool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) @@ -228,7 +225,7 @@ var shellCommand = &cli.Command{ // Initialize updater and get expected version opt := update.DefaultOptions opt.RootDirectory = c.String("root-dir") - opt.ServerURL = c.String("notary-url") + opt.ServerURL = c.String("tuf-url") opt.LocalStore = badgerstore.New(db.DB) updater, err := update.New(opt) if err != nil { @@ -237,11 +234,8 @@ var shellCommand = &cli.Command{ if err := updater.UpdateMetadata(); err != nil { return err } - osquerydPath, err := updater.Get( - "osqueryd", - constant.PlatformName, - c.String("osqueryd-version"), - ) + + osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) if err != nil { return err } diff --git a/pkg/osquery/flags.go b/pkg/osquery/flags.go index 04bffea54b..065286baae 100644 --- a/pkg/osquery/flags.go +++ b/pkg/osquery/flags.go @@ -1,5 +1,6 @@ package osquery +// FleetFlags is the set of flags to pass to osquery when connecting to Fleet. func FleetFlags(hostname string) []string { return []string{ "--tls_hostname=" + hostname, diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 070bc45615..212dda94cf 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -1,3 +1,4 @@ +// package osquery implements a runtime for osqueryd. package osquery import ( @@ -11,12 +12,15 @@ import ( "github.com/rs/zerolog/log" ) +// Runner is a specialized runner for osquery. It is designed with Execute and +// Interrupt functions to be compatible with oklog/run. type Runner struct { proc *process.Process cmd *exec.Cmd cancel func() } +// NewRunner creates a new osquery runner given the provided functional options. func NewRunner(options ...func(*Runner) error) (*Runner, error) { r := &Runner{} @@ -45,6 +49,7 @@ func NewRunner(options ...func(*Runner) error) (*Runner, error) { return r, nil } +// WithFlags adds additional flags to the osqueryd invocation. func WithFlags(flags []string) func(*Runner) error { return func(r *Runner) error { r.cmd.Args = append(r.cmd.Args, flags...) @@ -52,6 +57,8 @@ func WithFlags(flags []string) func(*Runner) error { } } +// WithEnv adds additional environment variables to the osqueryd invocation. +// Inputs should be in the form "KEY=VAL". func WithEnv(env []string) func(*Runner) error { return func(r *Runner) error { r.cmd.Env = append(r.cmd.Env, env...) @@ -59,6 +66,7 @@ func WithEnv(env []string) func(*Runner) error { } } +// WithPath sets the path of the osqueryd binary to execute. func WithPath(path string) func(*Runner) error { return func(r *Runner) error { r.cmd.Path = path @@ -77,6 +85,9 @@ func WithShell() func(*Runner) error { } } +// Execute begins running osqueryd and returns when the process exits. The +// process may not be restarted after exit. Instead create a new one with +// NewRunner. func (r *Runner) Execute() error { log.Debug().Str("cmd", r.cmd.String()).Msg("run osqueryd") @@ -94,6 +105,7 @@ func (r *Runner) Execute() error { return nil } +// Runner interrupts the running osquery process. func (r *Runner) Interrupt(err error) { log.Debug().Msg("interrupt osquery") r.cancel() diff --git a/pkg/update/update.go b/pkg/update/update.go index afc2001dd0..7740040172 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -92,26 +92,30 @@ func New(opt Options) (*Updater, error) { } func (u *Updater) UpdateMetadata() error { - if _, err := u.client.Update(); err != nil && errors.Is(err, &client.ErrLatestSnapshot{}) { - return errors.Wrap(err, "update metadata") + if _, err := u.client.Update(); err != nil { + // An error is returned if we are already up-to-date. We can ignore that + // error. + if !client.IsLatestSnapshot(errors.Cause(err)) { + return errors.Wrap(err, "update metadata") + } } return nil } -func makeRepoPath(name, platform, version string) string { - path := path.Join(name, platform, version, name+constant.ExecutableExtension) +func makeRepoPath(name, version string) string { + path := path.Join(name, constant.PlatformName, version, name+constant.ExecutableExtension) return path } -func makeLocalPath(name, platform, version string) string { - path := filepath.Join(name, version, name+constant.ExecutableExtension) +func makeLocalPath(name, version string) string { + path := filepath.Join(name, constant.PlatformName, name+constant.ExecutableExtension) return path } // Lookup looks up the provided target in the local target metadata. This should // be called after UpdateMetadata. -func (u *Updater) Lookup(name, platform, version string) (*data.TargetFileMeta, error) { - target, err := u.client.Target(makeRepoPath(name, platform, version)) +func (u *Updater) Lookup(name, version string) (*data.TargetFileMeta, error) { + target, err := u.client.Target(makeRepoPath(name, version)) if err != nil { return nil, errors.Wrapf(err, "lookup target %v", target) } @@ -131,9 +135,9 @@ func (u *Updater) Targets() (data.TargetFiles, error) { // Get returns the local path to the specified target. The target is downloaded // if it does not yet exist locally or the hash does not match. -func (u *Updater) Get(name, platform, version string) (string, error) { - localPath := u.pathFromRoot(makeLocalPath(name, platform, version)) - repoPath := makeRepoPath(name, platform, version) +func (u *Updater) Get(name, version string) (string, error) { + localPath := u.pathFromRoot(makeLocalPath(name, version)) + repoPath := makeRepoPath(name, version) stat, err := os.Stat(localPath) if err != nil { log.Debug().Err(err).Msg("stat file") @@ -143,7 +147,7 @@ func (u *Updater) Get(name, platform, version string) (string, error) { return "", errors.Errorf("expected %s to be regular file", localPath) } - meta, err := u.Lookup(name, platform, version) + meta, err := u.Lookup(name, version) if err != nil { return "", err } diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index 3a5333a969..b0816d7df2 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -36,21 +37,35 @@ func assertDir(t *testing.T, path string) { func TestMakeRepoPath(t *testing.T) { t.Parallel() - testCases := []struct { + type testCase struct { name string - platform string version string expected string - }{ - {name: "osqueryd", platform: "linux", version: "4.6.0", expected: "osqueryd/linux/4.6.0/osqueryd"}, - {name: "osqueryd", platform: "windows", version: "3.3.2", expected: "osqueryd/windows/3.3.2/osqueryd.exe"}, + } + var testCases []testCase + switch runtime.GOOS { + case "linux": + testCases = append(testCases, + testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/linux/4.6.0/osqueryd"}, + testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/linux/3.3.2/osqueryd"}, + ) + case "darwin": + testCases = append(testCases, + testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/macos/4.6.0/osqueryd"}, + testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/macos/3.3.2/osqueryd"}, + ) + case "windows": + testCases = append(testCases, + testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/windows/4.6.0/osqueryd.exe"}, + testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/windows/3.3.2/osqueryd.exe"}, + ) } for _, tt := range testCases { t.Run(tt.expected, func(t *testing.T) { t.Parallel() - assert.Equal(t, tt.expected, makeRepoPath(tt.name, tt.platform, tt.version)) + assert.Equal(t, tt.expected, makeRepoPath(tt.name, tt.version)) }) } } From 7dc1677aac2058a628a66a7c0dc3d0dd708a0657 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 15 Jan 2021 09:04:45 -0800 Subject: [PATCH 030/115] Update InsecureTransport comment --- pkg/update/update.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/update/update.go b/pkg/update/update.go index 7740040172..3e69a58f8e 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -36,7 +36,8 @@ type Options struct { // ServerURL is the URL of the update server. ServerURL string // InsecureTransport skips TLS certificate verification in the transport if - // set to true. + // set to true. Best to leave this on, but due to the file signing any + // tampering by a MitM should be detectable. InsecureTransport bool // RootKeys is the JSON encoded root keys to use to bootstrap trust. RootKeys string From 606e3929cdba39bf225763ad3e5121c627f74f6a Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 15 Jan 2021 14:33:46 -0800 Subject: [PATCH 031/115] Move main to cmd/orbit --- main.go => cmd/orbit/orbit.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename main.go => cmd/orbit/orbit.go (100%) diff --git a/main.go b/cmd/orbit/orbit.go similarity index 100% rename from main.go rename to cmd/orbit/orbit.go From bf834895d3a4e9319ffba8634617813ab0309552 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 25 Jan 2021 19:53:51 -0800 Subject: [PATCH 032/115] PoC of packaging and autoupdate working together - Linux packaging works (tested on Ubuntu 20) - Packaging needs to be made configurable via flags --- cmd/orbit/orbit.go | 61 ++- cmd/package/package.go | 201 +++++++ go.mod | 5 +- go.sum | 690 +++++++++++++++++++++++++ pkg/constant/constant.go | 15 +- pkg/constant/constant_darwin.go | 3 +- pkg/constant/constant_linux.go | 3 +- pkg/constant/constant_windows.go | 3 +- pkg/insecure/proxy.go | 4 +- pkg/osquery/osquery.go | 52 +- pkg/update/filestore/filestore.go | 94 ++++ pkg/update/filestore/filestore_test.go | 66 +++ pkg/update/update.go | 38 +- pkg/update/update_test.go | 34 +- 14 files changed, 1177 insertions(+), 92 deletions(-) create mode 100644 cmd/package/package.go create mode 100644 pkg/update/filestore/filestore.go create mode 100644 pkg/update/filestore/filestore_test.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 572dd2e602..1ebcb37352 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -13,7 +13,7 @@ import ( "github.com/fleetdm/orbit/pkg/insecure" "github.com/fleetdm/orbit/pkg/osquery" "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/badgerstore" + "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/oklog/run" "github.com/pkg/errors" "github.com/rs/zerolog" @@ -22,15 +22,20 @@ import ( ) const ( - tufURL = "https://tuf.fleetctl.com" - certPath = "/tmp/fleet.pem" + tufURL = "https://tuf.fleetctl.com" + certPath = "/tmp/fleet.pem" + defaultRootDir = "/var/lib/fleet/orbit" ) func main() { + log.Logger = log.Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, + ) + zerolog.SetGlobalLevel(zerolog.InfoLevel) + app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" - defaultRootDir := "/usr/local/fleet" app.Commands = []*cli.Command{ shellCommand, } @@ -68,7 +73,6 @@ func main() { }, } app.Action = func(c *cli.Context) error { - zerolog.SetGlobalLevel(zerolog.InfoLevel) if c.Bool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) } @@ -87,17 +91,23 @@ func main() { } }() + localStore, err := filestore.New(filepath.Join(c.String("root-dir"), "tuf-metadata.json")) + if err != nil { + log.Fatal().Err(err).Msg("failed to create local metadata store") + } + // Initialize updater and get expected version opt := update.DefaultOptions - opt.RootDirectory = c.String("tuf-dir") + opt.RootDirectory = c.String("root-dir") opt.ServerURL = c.String("tuf-url") - opt.LocalStore = badgerstore.New(db.DB) + opt.LocalStore = localStore + opt.InsecureTransport = c.Bool("insecure") updater, err := update.New(opt) if err != nil { return err } if err := updater.UpdateMetadata(); err != nil { - return err + log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) if err != nil { @@ -106,6 +116,7 @@ func main() { var g run.Group var options []func(*osquery.Runner) error + options = append(options, osquery.WithDataPath(c.String("root-dir"))) fleetURL := c.String("fleet-url") @@ -117,6 +128,10 @@ func main() { g.Add( func() error { + log.Info(). + Str("addr", fmt.Sprintf("localhost:%d", proxy.Port)). + Str("target", c.String("fleet-url")). + Msg("using insecure TLS proxy") err := proxy.InsecureServeTLS() return err }, @@ -155,16 +170,16 @@ func main() { ) } - options = append(options, - osquery.WithFlags([]string{"--verbose"}), - ) + if c.Bool("debug") { + options = append(options, + osquery.WithFlags([]string{"--verbose", "--tls_dump"}), + ) + } - options = append(options, osquery.WithPath(osquerydPath)) - options = append(options, osquery.WithShell()) options = append(options, osquery.WithFlags([]string(c.Args().Slice()))) // Create an osquery runner with the provided options - r, _ := osquery.NewRunner(options...) + r, _ := osquery.NewRunner(osquerydPath, options...) g.Add(r.Execute, r.Interrupt) // Install a signal handler @@ -200,10 +215,6 @@ var shellCommand = &cli.Command{ }, }, Action: func(c *cli.Context) error { - log.Logger = log.Output( - zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, - ) - zerolog.SetGlobalLevel(zerolog.InfoLevel) if c.Bool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) } @@ -222,19 +233,24 @@ var shellCommand = &cli.Command{ } }() + localStore, err := filestore.New(filepath.Join(c.String("root-dir"), "tuf-metadata.json")) + if err != nil { + log.Fatal().Err(err).Msg("failed to create local metadata store") + } + // Initialize updater and get expected version opt := update.DefaultOptions opt.RootDirectory = c.String("root-dir") opt.ServerURL = c.String("tuf-url") - opt.LocalStore = badgerstore.New(db.DB) + opt.LocalStore = localStore + opt.InsecureTransport = c.Bool("insecure") updater, err := update.New(opt) if err != nil { return err } if err := updater.UpdateMetadata(); err != nil { - return err + log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) if err != nil { return err @@ -244,9 +260,10 @@ var shellCommand = &cli.Command{ // Create an osquery runner with the provided options r, _ := osquery.NewRunner( + osquerydPath, osquery.WithShell(), - osquery.WithPath(osquerydPath), osquery.WithFlags([]string(c.Args().Slice())), + osquery.WithDataPath(c.String("root-dir")), ) g.Add(r.Execute, r.Interrupt) diff --git a/cmd/package/package.go b/cmd/package/package.go new file mode 100644 index 0000000000..7f04e31973 --- /dev/null +++ b/cmd/package/package.go @@ -0,0 +1,201 @@ +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "time" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" + "github.com/goreleaser/nfpm/v2" + "github.com/goreleaser/nfpm/v2/deb" + "github.com/goreleaser/nfpm/v2/files" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" +) + +func main() { + log.Logger = log.Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, + ) + zerolog.SetGlobalLevel(zerolog.InfoLevel) + + app := cli.NewApp() + app.Name = "Orbit osquery" + app.Usage = "A powered-up, (near) drop-in replacement for osquery" + app.Commands = []*cli.Command{} + app.Flags = []cli.Flag{ + &cli.BoolFlag{ + Name: "debug", + Usage: "Enable debug logging", + }, + } + app.Action = buildLinux + + if err := app.Run(os.Args); err != nil { + log.Fatal().Err(err).Msg("package failed") + } +} + +func buildLinux(c *cli.Context) error { + log.Logger = log.Output( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, + ) + zerolog.SetGlobalLevel(zerolog.InfoLevel) + + if c.Bool("debug") { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "filesystem") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create filesystem dir") + } + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + systemdRoot := filepath.Join(filesystemRoot, "usr", "lib", "systemd", "system") + if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create systemd dir") + } + if err := ioutil.WriteFile( + filepath.Join(systemdRoot, "orbit.service"), + []byte(` +[Unit] +Description=The osquery Daemon +After=network.service syslog.service + +[Service] +TimeoutStartSec=0 +ExecStart=/usr/local/bin/orbit --insecure --fleet-url=https://10.0.0.115:8080 --enroll-secret=s96I5x42hhN6c/kqxnpnX2ODkVJBVrOP +Restart=on-failure +KillMode=control-group +KillSignal=SIGTERM +CPUQuota=20% + +[Install] +WantedBy=multi-user.target +`), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write systemd unit") + } + + localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) + if err != nil { + return errors.Wrap(err, "failed to create local metadata store") + } + opt := update.DefaultOptions + opt.RootDirectory = orbitRoot + opt.ServerURL = "https://tuf.fleetctl.com" + opt.LocalStore = localStore + opt.Platform = "linux" + + updater, err := update.New(opt) + if err != nil { + return errors.Wrap(err, "failed to init updater") + } + if err := updater.UpdateMetadata(); err != nil { + return errors.Wrap(err, "failed to update metadata") + } + osquerydPath, err := updater.Get("osqueryd", "stable") + if err != nil { + return errors.Wrap(err, "failed to get osqueryd") + } + log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + + contents := files.Contents{ + &files.Content{ + Source: filepath.Join(filesystemRoot, "**"), + Destination: "/", + }, + &files.Content{ + Source: "orbit", + Destination: "/var/lib/fleet/orbit/orbit", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode, + }, + }, + &files.Content{ + Source: "/var/lib/fleet/orbit/orbit", + Destination: "/usr/local/bin/orbit", + Type: "symlink", + FileInfo: &files.ContentFileInfo{ + // TODO follow up on nfpm not respecting this + // https://github.com/goreleaser/nfpm/issues/286 + Mode: constant.DefaultExecutableMode | os.ModeSymlink, + }, + }, + } + contents, err = files.ExpandContentGlobs(contents, false) + if err != nil { + return errors.Wrap(err, "glob contents") + } + for _, c := range contents { + log.Debug().Interface("file", c).Msg("added file") + } + + postInstall := `#!/bin/sh + +# If we have a systemd, daemon-reload away now +if [ -x /bin/systemctl ] && pidof systemd ; then + /bin/systemctl daemon-reload 2>/dev/null 2>&1 && /bin/systemctl start orbit.service 2>&1 +fi +` + postInstallPath := filepath.Join(tmpDir, "postinstall.sh") + if err := ioutil.WriteFile( + postInstallPath, + []byte(postInstall), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write postinstall") + } + + info := &nfpm.Info{ + Name: "orbit-osquery", + Version: "0.0.1", + Description: "Osquery launcher and autoupdater", + Arch: "amd64", + Maintainer: "FleetDM Engineers ", + Homepage: "https://github.com/fleetdm/orbit", + Overridables: nfpm.Overridables{ + Contents: contents, + EmptyFolders: []string{ + "/var/log/osquery", + "/var/log/fleet/orbit", + }, + Scripts: nfpm.Scripts{ + PostInstall: postInstallPath, + }, + }, + } + + pkger := deb.Default + filename := pkger.ConventionalFileName(info) + + out, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode) + if err != nil { + return errors.Wrap(err, "open output file") + } + defer out.Close() + + if err := deb.Default.Package(info, out); err != nil { + return errors.Wrap(err, "write deb package") + } + log.Info().Str("path", filename).Msg("wrote deb package") + + return nil +} diff --git a/go.mod b/go.mod index 9c51eabeff..de873a5b89 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,14 @@ go 1.15 require ( github.com/dgraph-io/badger/v2 v2.2007.2 - github.com/golang/protobuf v1.3.4 // indirect + github.com/goreleaser/nfpm/v2 v2.2.2 github.com/kr/text v0.2.0 // indirect github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.20.0 - github.com/stretchr/objx v0.2.0 // indirect github.com/stretchr/testify v1.6.1 github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 + github.com/urfave/cli v1.22.5 github.com/urfave/cli/v2 v2.3.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect - golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e // indirect ) diff --git a/go.sum b/go.sum index 8e881d361c..9a8001f3c0 100644 --- a/go.sum +++ b/go.sum @@ -1,66 +1,438 @@ +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Djarvur/go-err113 v0.1.0 h1:uCRZZOdMQ0TZPHYTdYpoC0bLYJKPEHPUJ8MeAa51lNU= +github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= +github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/ashanbrown/forbidigo v1.0.0 h1:QdNXBduDUopc3GW+YVYZn8jzmIMklQiCfdN2N5+dQeE= +github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyafc3ntEGh2BBAg= +github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a h1:/U9tbJzDRof4fOR51vwzWdIBsIH6R2yU0KG1MBRM2Js= +github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= +github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8= +github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daixiang0/gci v0.2.4/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4= +github.com/daixiang0/gci v0.2.7 h1:bosLNficubzJZICsVzxuyNc6oAbdz0zcqLG2G/RxtY4= +github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= +github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= +github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-critic/go-critic v0.5.2 h1:3RJdgf6u4NZUumoP8nzbqiiNT8e1tC2Oc7jlgqre/IA= +github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= +github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= +github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= +github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d h1:pXTK/gkVNs7Zyy7WKgLXmpQ5bHTrq5GDsp8R9Qs67g0= +github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.33.0/go.mod h1:zMnMLSCaDlrXExYsuq2LOweE9CHVqYk5jexk23UsjYM= +github.com/golangci/golangci-lint v1.34.1 h1:xf1yVlLBNeCIoOHWXhwqnUeaqzONllRSgiLSahNt0Mw= +github.com/golangci/golangci-lint v1.34.1/go.mod h1:6Bnn7T0JYin7uukitgL6f9E9auQatlT0RMNOKG9lSHU= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= +github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 h1:XQKc8IYQOeRwVs36tDrEmTgDgP88d5iEURwpmtiAlOM= +github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= +github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/goreleaser/chglog v0.1.2 h1:tdzAb/ILeMnphzI9zQ7Nkq+T8R9qyXli8GydD8plFRY= +github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= +github.com/goreleaser/fileglob v0.3.1 h1:OTFDWqUUHjQazk2N5GdUqEbqT/grBnRARaAXsV07q1Y= +github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= +github.com/goreleaser/nfpm v1.10.3 h1:NzpWKKzSFr7JOn55XN0SskyFOjP6BkvRt3JujoX8fws= +github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= +github.com/goreleaser/nfpm/v2 v2.2.2 h1:aLGEqhMDcSNg1RHwzUBHwRUbmiK8HfD1sTq8bG7/WMc= +github.com/goreleaser/nfpm/v2 v2.2.2/go.mod h1:WtPzYQh+Ls57prS9RzXegrGejqILUS1aZibXHTTJ8eI= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/analysisutil v0.6.1 h1:/1JkoHe4DVxur+0wPvi26FoQfe1E3ZGqIXS3aaSLiaw= +github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg= +github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= +github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= +github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk= +github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= +github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= +github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= +github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= +github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e h1:2U5rOmpaB96l35w+NDjMtmmrp2e6a6AJKoc4B5+7UwA= +github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.1.0 h1:4ykwscnAFeHJruT+EY3M3vdeP8uXMh0VV2E61iR7XD8= +github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= +github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= +github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= +github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= +github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4= +github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= +github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw= +github.com/quasilyte/go-ruleguard v0.2.1 h1:56eRm0daAyny9UhJnmtJW/UyLZQusukBAB8oT8AHKHo= +github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE= +github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= @@ -68,67 +440,385 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= +github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro= +github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= +github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= +github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= +github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= +github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= +github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 h1:iGnD/q9160NWqKZZ5vY4p0dMiYMRknzctfSkqA4nBDw= github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug= +github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= +github.com/tetafro/godot v1.3.2 h1:HzWC3XjadkyeuBZxkfAFNY20UVvle0YD51I6zf6RKlU= +github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 h1:Zn+mA4qTRyao2Petd+YovKaFOUuxDj158kqCIqvwTow= github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw= +github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= +github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756 h1:zV5mu0ESwb+WnzqVaW2z1DdbAP0S46UtjY8DHQupQP4= +github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= +github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= +github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65 h1:Y0bLA422kvb32uZI4fy/Plop/Tbld0l9pSzl+j1FWok= +github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= +github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= +github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= +github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPehI0R024zxjDnw3esPA= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE= +golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2 h1:vEtypaVub6UvKkiXZ2xx9QIvp9TL7sI7xp7vdi2kezA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc= +honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= +mvdan.cc/gofumpt v0.0.0-20200802201014-ab5a8192947d/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws= +mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475 h1:5ZmJGYyuTlhdlIpRxSFhdJqkXQweXETFCEaLhRAX3e8= +mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY= +mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go index ce7ed7692b..8037198348 100644 --- a/pkg/constant/constant.go +++ b/pkg/constant/constant.go @@ -2,10 +2,21 @@ package constant const ( // DefaultDirMode is the default file mode to apply to created directories. - DefaultDirMode = 0o700 + DefaultDirMode = 0o755 // DefaultFileMode is the default file mode to apply to created files. DefaultFileMode = 0o600 // DefaultExecutableMode is the default file mode to apply to created // executable files. - DefaultExecutableMode = 0o700 + DefaultExecutableMode = 0o755 ) + +// ExecutableExtension returns the extension used for executables on the +// provided platform. +func ExecutableExtension(platform string) string { + switch platform { + case "windows": + return ".exe" + default: + return "" + } +} diff --git a/pkg/constant/constant_darwin.go b/pkg/constant/constant_darwin.go index 9a9845a243..879e60fc25 100644 --- a/pkg/constant/constant_darwin.go +++ b/pkg/constant/constant_darwin.go @@ -1,6 +1,5 @@ package constant const ( - PlatformName = "macos" - ExecutableExtension = "" + PlatformName = "macos" ) diff --git a/pkg/constant/constant_linux.go b/pkg/constant/constant_linux.go index 5ce35bd0da..dd2eff1e0d 100644 --- a/pkg/constant/constant_linux.go +++ b/pkg/constant/constant_linux.go @@ -1,6 +1,5 @@ package constant const ( - PlatformName = "linux" - ExecutableExtension = "" + PlatformName = "linux" ) diff --git a/pkg/constant/constant_windows.go b/pkg/constant/constant_windows.go index 6601de54a0..2e444d9990 100644 --- a/pkg/constant/constant_windows.go +++ b/pkg/constant/constant_windows.go @@ -1,6 +1,5 @@ package constant const ( - PlatformName = "windows" - ExecutableExtension = ".exe" + PlatformName = "windows" ) diff --git a/pkg/insecure/proxy.go b/pkg/insecure/proxy.go index 44aa67f4b5..605f6ca4bc 100644 --- a/pkg/insecure/proxy.go +++ b/pkg/insecure/proxy.go @@ -149,9 +149,9 @@ func newProxyHandler(hostname string) (*httputil.ReverseProxy, error) { reverseProxy := &httputil.ReverseProxy{ Director: func(req *http.Request) { - req.Host = hostname + req.Host = target.Host req.URL.Scheme = "https" - req.URL.Host = hostname + req.URL.Host = target.Host req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) }, } diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 212dda94cf..985d4af28d 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -5,8 +5,10 @@ import ( "context" "os" "os/exec" + "path/filepath" "time" + "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/process" "github.com/pkg/errors" "github.com/rs/zerolog/log" @@ -21,18 +23,10 @@ type Runner struct { } // NewRunner creates a new osquery runner given the provided functional options. -func NewRunner(options ...func(*Runner) error) (*Runner, error) { +func NewRunner(path string, options ...func(*Runner) error) (*Runner, error) { r := &Runner{} - // TODO set path and flags appropriately - cmd := exec.Command( - "osqueryd", - "--pidfile=/tmp/osquery.pid", - "--database_path=/tmp/osquery.test.db", - "--extensions_socket=/tmp/osquery.em", - "--config_path=/tmp/osquery.conf", - "--logger_path=/tmp", - ) + cmd := exec.Command(path) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -66,14 +60,6 @@ func WithEnv(env []string) func(*Runner) error { } } -// WithPath sets the path of the osqueryd binary to execute. -func WithPath(path string) func(*Runner) error { - return func(r *Runner) error { - r.cmd.Path = path - return nil - } -} - // WithShell adds the -S flag to run an osqueryi shell. func WithShell() func(*Runner) error { return func(r *Runner) error { @@ -85,6 +71,36 @@ func WithShell() func(*Runner) error { } } +func WithDataPath(path string) func(*Runner) error { + return func(r *Runner) error { + if err := os.MkdirAll(filepath.Join(path, "logs"), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize osquery data path") + } + + r.cmd.Args = append(r.cmd.Args, + "--pidfile="+filepath.Join(path, "osquery.pid"), + "--database_path="+filepath.Join(path, "osquery.db"), + "--extensions_socket="+filepath.Join(path, "osquery.em"), + "--config_path="+filepath.Join(path, "osquery.conf"), + ) + return nil + } +} + +func WithLogPath(path string) func(*Runner) error { + return func(r *Runner) error { + if err := os.MkdirAll(path, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize osquery log path") + } + + r.cmd.Args = append(r.cmd.Args, + "--logger_path="+path, + ) + + return nil + } +} + // Execute begins running osqueryd and returns when the process exits. The // process may not be restarted after exit. Instead create a new one with // NewRunner. diff --git a/pkg/update/filestore/filestore.go b/pkg/update/filestore/filestore.go new file mode 100644 index 0000000000..0248795411 --- /dev/null +++ b/pkg/update/filestore/filestore.go @@ -0,0 +1,94 @@ +package filestore + +import ( + "encoding/json" + "os" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/pkg/errors" + "github.com/theupdateframework/go-tuf/client" +) + +type fileStore struct { + filename string + metadata metadataMap +} + +type metadataMap map[string]json.RawMessage + +func New(filename string) (client.LocalStore, error) { + store := &fileStore{filename: filename} + if err := store.readData(); err != nil { + return nil, err + } + + return store, nil +} + +// SetMeta stores the provided metadata. +func (s *fileStore) SetMeta(name string, meta json.RawMessage) error { + if s.metadata == nil { + if err := s.readData(); err != nil { + return err + } + } + + s.metadata[name] = meta + if err := s.writeData(); err != nil { + return err + } + + return nil +} + +// GetMeta returns all of the saved metadata. +func (s *fileStore) GetMeta() (map[string]json.RawMessage, error) { + if s.metadata == nil { + if err := s.readData(); err != nil { + return nil, err + } + } + + return s.metadata, nil +} + +func (s *fileStore) readData() error { + stat, err := os.Stat(s.filename) + if err != nil && !os.IsNotExist(err) { + return errors.Wrap(err, "stat file store") + } else if os.IsNotExist(err) { + // initialize empty + s.metadata = metadataMap{} + return nil + } else if !stat.Mode().IsRegular() { + return errors.New("expected file store to be regular file") + } + + f, err := os.Open(s.filename) + if err != nil { + return errors.Wrap(err, "open file store") + } + defer f.Close() + + var meta metadataMap + if err := json.NewDecoder(f).Decode(&meta); err != nil { + return errors.Wrap(err, "read file store") + } + + s.metadata = meta + return nil +} + +func (s *fileStore) writeData() error { + f, err := os.OpenFile(s.filename, os.O_RDWR|os.O_CREATE, constant.DefaultFileMode) + if err != nil { + return errors.Wrap(err, "open file store") + } + defer f.Close() + + if err := json.NewEncoder(f).Encode(s.metadata); err != nil { + return errors.Wrap(err, "read file store") + } + + return nil +} diff --git a/pkg/update/filestore/filestore_test.go b/pkg/update/filestore/filestore_test.go new file mode 100644 index 0000000000..89ab97e3dc --- /dev/null +++ b/pkg/update/filestore/filestore_test.go @@ -0,0 +1,66 @@ +package filestore + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestFileStorePathError(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "filestore-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + require.NoError(t, os.MkdirAll(filepath.Join(tmpDir, "metadata.json"), constant.DefaultDirMode)) + + store, err := New(filepath.Join(tmpDir, "metadata.json")) + assert.Error(t, err) + assert.Nil(t, store) +} + +func TestFileStore(t *testing.T) { + t.Parallel() + + tmpDir, err := ioutil.TempDir("", "filestore-test") + require.NoError(t, err) + defer os.RemoveAll(tmpDir) + + store, err := New(filepath.Join(tmpDir, "metadata.json")) + require.NoError(t, err) + + expected := map[string]json.RawMessage{ + "test": json.RawMessage("{}"), + "test2": json.RawMessage("{}"), + "root.json": json.RawMessage(`[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"0994148e5242118d1d6a9a397a3646e0423545a37794a791c28aa39de3b0c523"}}]`), + } + + for k, v := range expected { + require.NoError(t, store.SetMeta(k, v)) + } + + res, err := store.GetMeta() + require.NoError(t, err) + assert.Equal(t, expected, res) + + // Reopen and check + store, err = New(filepath.Join(tmpDir, "metadata.json")) + require.NoError(t, err) + res, err = store.GetMeta() + require.NoError(t, err) + assert.Equal(t, expected, res) + + // Update and check + expected["test"] = json.RawMessage("[]") + require.NoError(t, store.SetMeta("test", expected["test"])) + res, err = store.GetMeta() + require.NoError(t, err) + assert.Equal(t, expected, res) +} diff --git a/pkg/update/update.go b/pkg/update/update.go index 3e69a58f8e..fc7b6ef29b 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -18,9 +18,7 @@ import ( ) const ( - binDir = "bin" - osqueryDir = "osquery" - orbitDir = "orbit" + binDir = "bin" ) // Updater is responsible for managing update state. @@ -43,6 +41,9 @@ type Options struct { RootKeys string // LocalStore is the local metadata store. LocalStore client.LocalStore + // Platform is the name of the platform to update for. In the default + // options this is the current platform. + Platform string } var ( @@ -53,6 +54,7 @@ var ( ServerURL: "https://tuf.fleetctl.com", LocalStore: client.MemoryLocalStore(), InsecureTransport: false, + Platform: constant.PlatformName, RootKeys: `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"0994148e5242118d1d6a9a397a3646e0423545a37794a791c28aa39de3b0c523"}}]`, } ) @@ -76,8 +78,16 @@ func New(opt Options) (*Updater, error) { if err := json.Unmarshal([]byte(opt.RootKeys), &rootKeys); err != nil { return nil, errors.Wrap(err, "unmarshal root keys") } - if err := tufClient.Init(rootKeys, 1); err != nil { - return nil, errors.Wrap(err, "init tuf client") + + meta, err := opt.LocalStore.GetMeta() + if err != nil || meta["root.json"] == nil { + var rootKeys []*data.Key + if err := json.Unmarshal([]byte(opt.RootKeys), &rootKeys); err != nil { + return nil, errors.Wrap(err, "unmarshal root keys") + } + if err := tufClient.Init(rootKeys, 1); err != nil { + return nil, errors.Wrap(err, "init tuf client") + } } updater := &Updater{ @@ -103,20 +113,18 @@ func (u *Updater) UpdateMetadata() error { return nil } -func makeRepoPath(name, version string) string { - path := path.Join(name, constant.PlatformName, version, name+constant.ExecutableExtension) - return path +func (u *Updater) RepoPath(name, version string) string { + return path.Join(name, u.opt.Platform, version, name+constant.ExecutableExtension(u.opt.Platform)) } -func makeLocalPath(name, version string) string { - path := filepath.Join(name, constant.PlatformName, name+constant.ExecutableExtension) - return path +func (u *Updater) LocalPath(name, version string) string { + return u.pathFromRoot(filepath.Join(binDir, name, u.opt.Platform, version, name+constant.ExecutableExtension(u.opt.Platform))) } // Lookup looks up the provided target in the local target metadata. This should // be called after UpdateMetadata. func (u *Updater) Lookup(name, version string) (*data.TargetFileMeta, error) { - target, err := u.client.Target(makeRepoPath(name, version)) + target, err := u.client.Target(u.RepoPath(name, version)) if err != nil { return nil, errors.Wrapf(err, "lookup target %v", target) } @@ -137,8 +145,8 @@ func (u *Updater) Targets() (data.TargetFiles, error) { // Get returns the local path to the specified target. The target is downloaded // if it does not yet exist locally or the hash does not match. func (u *Updater) Get(name, version string) (string, error) { - localPath := u.pathFromRoot(makeLocalPath(name, version)) - repoPath := makeRepoPath(name, version) + localPath := u.LocalPath(name, version) + repoPath := u.RepoPath(name, version) stat, err := os.Stat(localPath) if err != nil { log.Debug().Err(err).Msg("stat file") @@ -201,8 +209,6 @@ func (u *Updater) pathFromRoot(parts ...string) string { func (u *Updater) initializeDirectories() error { for _, dir := range []string{ u.pathFromRoot(binDir), - u.pathFromRoot(binDir, osqueryDir), - u.pathFromRoot(binDir, orbitDir), } { err := os.MkdirAll(dir, constant.DefaultDirMode) if err != nil { diff --git a/pkg/update/update_test.go b/pkg/update/update_test.go index b0816d7df2..1307357336 100644 --- a/pkg/update/update_test.go +++ b/pkg/update/update_test.go @@ -4,7 +4,6 @@ import ( "io/ioutil" "os" "path/filepath" - "runtime" "testing" "github.com/stretchr/testify/assert" @@ -24,8 +23,6 @@ func TestInitializeDirectories(t *testing.T) { err = updater.initializeDirectories() require.NoError(t, err) assertDir(t, filepath.Join(tmpDir, binDir)) - assertDir(t, filepath.Join(tmpDir, binDir, osqueryDir)) - assertDir(t, filepath.Join(tmpDir, binDir, orbitDir)) } func assertDir(t *testing.T, path string) { @@ -37,35 +34,26 @@ func assertDir(t *testing.T, path string) { func TestMakeRepoPath(t *testing.T) { t.Parallel() - type testCase struct { + testCases := []struct { name string version string + platform string expected string - } - var testCases []testCase - switch runtime.GOOS { - case "linux": - testCases = append(testCases, - testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/linux/4.6.0/osqueryd"}, - testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/linux/3.3.2/osqueryd"}, - ) - case "darwin": - testCases = append(testCases, - testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/macos/4.6.0/osqueryd"}, - testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/macos/3.3.2/osqueryd"}, - ) - case "windows": - testCases = append(testCases, - testCase{name: "osqueryd", version: "4.6.0", expected: "osqueryd/windows/4.6.0/osqueryd.exe"}, - testCase{name: "osqueryd", version: "3.3.2", expected: "osqueryd/windows/3.3.2/osqueryd.exe"}, - ) + }{ + {platform: "linux", name: "osqueryd", version: "4.6.0", expected: "osqueryd/linux/4.6.0/osqueryd"}, + {platform: "linux", name: "osqueryd", version: "3.3.2", expected: "osqueryd/linux/3.3.2/osqueryd"}, + {platform: "macos", name: "osqueryd", version: "4.6.0", expected: "osqueryd/macos/4.6.0/osqueryd"}, + {platform: "macos", name: "osqueryd", version: "3.3.2", expected: "osqueryd/macos/3.3.2/osqueryd"}, + {platform: "windows", name: "osqueryd", version: "4.6.0", expected: "osqueryd/windows/4.6.0/osqueryd.exe"}, + {platform: "windows", name: "osqueryd", version: "3.3.2", expected: "osqueryd/windows/3.3.2/osqueryd.exe"}, } for _, tt := range testCases { t.Run(tt.expected, func(t *testing.T) { t.Parallel() - assert.Equal(t, tt.expected, makeRepoPath(tt.name, tt.version)) + u := Updater{opt: Options{Platform: tt.platform}} + assert.Equal(t, tt.expected, u.RepoPath(tt.name, tt.version)) }) } } From 6ba2ce9bdc9f46f0ff8b4db24935bdb06c42cb92 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 26 Jan 2021 11:10:03 -0800 Subject: [PATCH 033/115] Add environment variables for flags --- cmd/orbit/orbit.go | 41 ++++++++++++++++++++++++----------------- tools/ubuntu/Dockerfile | 5 +++++ 2 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 tools/ubuntu/Dockerfile diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 1ebcb37352..807ac3b886 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -41,35 +41,42 @@ func main() { } app.Flags = []cli.Flag{ &cli.StringFlag{ - Name: "root-dir", - Usage: "Root directory for Orbit state", - Value: defaultRootDir, + Name: "root-dir", + Usage: "Root directory for Orbit state", + Value: defaultRootDir, + EnvVars: []string{"ORBIT_ROOT_DIR"}, }, &cli.BoolFlag{ - Name: "insecure", - Usage: "Disable TLS certificate verification", + Name: "insecure", + Usage: "Disable TLS certificate verification", + EnvVars: []string{"ORBIT_INSECURE"}, }, &cli.StringFlag{ - Name: "fleet-url", - Usage: "URL (host:port) to Fleet server", + Name: "fleet-url", + Usage: "URL (host:port) of Fleet server", + EnvVars: []string{"ORBIT_FLEET_URL"}, }, &cli.StringFlag{ - Name: "tuf-url", - Usage: "URL to TUF update server", - Value: tufURL, + Name: "tuf-url", + Usage: "URL of TUF update server", + Value: tufURL, + EnvVars: []string{"ORBIT_TUF_URL"}, }, &cli.StringFlag{ - Name: "enroll-secret", - Usage: "Enroll secret for authenticating to Fleet server", + Name: "enroll-secret", + Usage: "Enroll secret for authenticating to Fleet server", + EnvVars: []string{"ENROLL_SECRET"}, }, &cli.StringFlag{ - Name: "osqueryd-version", - Usage: "Version of osqueryd to use", - Value: "stable", + Name: "osqueryd-version", + Usage: "Version of osqueryd to use", + Value: "stable", + EnvVars: []string{"ORBIT_OSQUERYD_VERSION"}, }, &cli.BoolFlag{ - Name: "debug", - Usage: "Enable debug logging", + Name: "debug", + Usage: "Enable debug logging", + EnvVars: []string{"ORBIT_DEBUG"}, }, } app.Action = func(c *cli.Context) error { diff --git a/tools/ubuntu/Dockerfile b/tools/ubuntu/Dockerfile new file mode 100644 index 0000000000..676b6cb488 --- /dev/null +++ b/tools/ubuntu/Dockerfile @@ -0,0 +1,5 @@ +FROM ubuntu + +RUN apt-get update &&\ + apt-get install -y ca-certificates &&\ + rm -rf /var/lib/apt/lists/* From ee3ee62801fea0afccd9a3e2109781d8b2a50502 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 26 Jan 2021 14:36:47 -0800 Subject: [PATCH 034/115] Expose configurations via packaging Fleet server and enroll secret can now be configured by flags in the packaging script. --- cmd/orbit/orbit.go | 24 ++--- cmd/package/package.go | 209 ++++++++++++++++++++++++++++++----------- 2 files changed, 167 insertions(+), 66 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 807ac3b886..eb31e759ba 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -65,13 +65,13 @@ func main() { &cli.StringFlag{ Name: "enroll-secret", Usage: "Enroll secret for authenticating to Fleet server", - EnvVars: []string{"ENROLL_SECRET"}, + EnvVars: []string{"ORBIT_ENROLL_SECRET"}, }, &cli.StringFlag{ - Name: "osqueryd-version", - Usage: "Version of osqueryd to use", + Name: "osquery-version", + Usage: "Version of osquery to use", Value: "stable", - EnvVars: []string{"ORBIT_OSQUERYD_VERSION"}, + EnvVars: []string{"ORBIT_OSQUERY_VERSION"}, }, &cli.BoolFlag{ Name: "debug", @@ -116,7 +116,7 @@ func main() { if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) + osquerydPath, err := updater.Get("osqueryd", c.String("osquery-version")) if err != nil { return err } @@ -212,13 +212,15 @@ var shellCommand = &cli.Command{ Usage: "Run the osqueryi shell", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "osqueryd-version", - Usage: "Version of osqueryd to use", - Value: "stable", + Name: "osquery-version", + Usage: "Version of osquery to use", + Value: "stable", + EnvVars: []string{"ORBIT_OSQUERY_VERSION"}, }, &cli.BoolFlag{ - Name: "debug", - Usage: "Enable debug logging", + Name: "debug", + Usage: "Enable debug logging", + EnvVars: []string{"ORBIT_DEBUG"}, }, }, Action: func(c *cli.Context) error { @@ -258,7 +260,7 @@ var shellCommand = &cli.Command{ if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-version")) + osquerydPath, err := updater.Get("osqueryd", c.String("osquery-version")) if err != nil { return err } diff --git a/cmd/package/package.go b/cmd/package/package.go index 7f04e31973..19777438ca 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "io/ioutil" "os" "path/filepath" + "text/template" "time" "github.com/fleetdm/orbit/pkg/constant" @@ -18,7 +20,15 @@ import ( "github.com/urfave/cli/v2" ) +type packageOptions struct { + FleetURL string + EnrollSecret string + StartService bool + Insecure bool +} + func main() { + var opt packageOptions log.Logger = log.Output( zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, ) @@ -29,27 +39,51 @@ func main() { app.Usage = "A powered-up, (near) drop-in replacement for osquery" app.Commands = []*cli.Command{} app.Flags = []cli.Flag{ + &cli.StringFlag{ + Name: "enroll-secret", + Usage: "Enroll secret for authenticating to Fleet server", + Destination: &opt.EnrollSecret, + }, + &cli.StringFlag{ + Name: "fleet-url", + Usage: "URL (host:port) of Fleet server", + Destination: &opt.FleetURL, + }, + &cli.BoolFlag{ + Name: "insecure", + Usage: "Disable TLS certificate verification", + Destination: &opt.Insecure, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", }, } - app.Action = buildLinux + app.Before = func(c *cli.Context) error { + if c.Bool("debug") { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + return nil + } + app.Action = func(c *cli.Context) error { + if opt.FleetURL != "" || opt.EnrollSecret != "" { + opt.StartService = true + + if opt.FleetURL == "" || opt.EnrollSecret == "" { + return errors.New("--enroll-secret and --fleet-url must be provided together") + } + } + + return buildLinux(opt) + } if err := app.Run(os.Args); err != nil { log.Fatal().Err(err).Msg("package failed") } } -func buildLinux(c *cli.Context) error { - log.Logger = log.Output( - zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, - ) - zerolog.SetGlobalLevel(zerolog.InfoLevel) - - if c.Bool("debug") { - zerolog.SetGlobalLevel(zerolog.DebugLevel) - } +func buildLinux(opt packageOptions) error { + // Initialize directories tmpDir, err := ioutil.TempDir("", "orbit-package") if err != nil { @@ -67,44 +101,34 @@ func buildLinux(c *cli.Context) error { return errors.Wrap(err, "create orbit dir") } - systemdRoot := filepath.Join(filesystemRoot, "usr", "lib", "systemd", "system") - if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create systemd dir") - } - if err := ioutil.WriteFile( - filepath.Join(systemdRoot, "orbit.service"), - []byte(` -[Unit] -Description=The osquery Daemon -After=network.service syslog.service + // Write files -[Service] -TimeoutStartSec=0 -ExecStart=/usr/local/bin/orbit --insecure --fleet-url=https://10.0.0.115:8080 --enroll-secret=s96I5x42hhN6c/kqxnpnX2ODkVJBVrOP -Restart=on-failure -KillMode=control-group -KillSignal=SIGTERM -CPUQuota=20% - -[Install] -WantedBy=multi-user.target -`), - constant.DefaultFileMode, - ); err != nil { + if err := writeSystemdUnit(opt, filesystemRoot); err != nil { return errors.Wrap(err, "write systemd unit") } + if err := writeEnvFile(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write env file") + } + + postInstallPath := filepath.Join(tmpDir, "postinstall.sh") + if err := writePostInstall(opt, postInstallPath); err != nil { + return errors.Wrap(err, "write postinstall script") + } + + // Initialize autoupdate metadata + localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) if err != nil { return errors.Wrap(err, "failed to create local metadata store") } - opt := update.DefaultOptions - opt.RootDirectory = orbitRoot - opt.ServerURL = "https://tuf.fleetctl.com" - opt.LocalStore = localStore - opt.Platform = "linux" + updateOpt := update.DefaultOptions + updateOpt.RootDirectory = orbitRoot + updateOpt.ServerURL = "https://tuf.fleetctl.com" + updateOpt.LocalStore = localStore + updateOpt.Platform = "linux" - updater, err := update.New(opt) + updater, err := update.New(updateOpt) if err != nil { return errors.Wrap(err, "failed to init updater") } @@ -117,6 +141,8 @@ WantedBy=multi-user.target } log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + // Pick up all file contents + contents := files.Contents{ &files.Content{ Source: filepath.Join(filesystemRoot, "**"), @@ -148,21 +174,7 @@ WantedBy=multi-user.target log.Debug().Interface("file", c).Msg("added file") } - postInstall := `#!/bin/sh - -# If we have a systemd, daemon-reload away now -if [ -x /bin/systemctl ] && pidof systemd ; then - /bin/systemctl daemon-reload 2>/dev/null 2>&1 && /bin/systemctl start orbit.service 2>&1 -fi -` - postInstallPath := filepath.Join(tmpDir, "postinstall.sh") - if err := ioutil.WriteFile( - postInstallPath, - []byte(postInstall), - constant.DefaultFileMode, - ); err != nil { - return errors.Wrap(err, "write postinstall") - } + // Build package info := &nfpm.Info{ Name: "orbit-osquery", @@ -182,7 +194,6 @@ fi }, }, } - pkger := deb.Default filename := pkger.ConventionalFileName(info) @@ -199,3 +210,91 @@ fi return nil } + +func writeSystemdUnit(optt packageOptions, rootPath string) error { + systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system") + if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create systemd dir") + } + if err := ioutil.WriteFile( + filepath.Join(systemdRoot, "orbit.service"), + []byte(` +[Unit] +Description=Fleet Orbit osquery +After=network.service syslog.service + +[Service] +TimeoutStartSec=0 +EnvironmentFile=/etc/default/orbit +ExecStart=/usr/local/bin/orbit +Restart=on-failure +KillMode=control-group +KillSignal=SIGTERM +CPUQuota=20% + +[Install] +WantedBy=multi-user.target +`), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var envTemplate = template.Must(template.New("env").Parse(` +{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} +{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} +{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} +`)) + +func writeEnvFile(opt packageOptions, rootPath string) error { + envRoot := filepath.Join(rootPath, "etc", "default") + if err := os.MkdirAll(envRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create env dir") + } + + var contents bytes.Buffer + if err := envTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile( + filepath.Join(envRoot, "orbit"), + contents.Bytes(), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var postInstallTemplate = template.Must(template.New("postinstall").Parse(` +#!/bin/sh + +# Exit on error +set -e + +# If we have a systemd, daemon-reload away now +if [ -x /bin/systemctl ] && pidof systemd ; then + /bin/systemctl daemon-reload 2>/dev/null 2>&1 +{{ if .StartService -}} + /bin/systemctl start orbit.service 2>&1 +{{- end}} +fi +`)) + +func writePostInstall(opt packageOptions, path string) error { + var contents bytes.Buffer + if err := postInstallTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} From 117708aa7b6510afa22ab9c561cde566cee63882 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 5 Feb 2021 19:08:07 -0800 Subject: [PATCH 035/115] Update root key metadata --- pkg/update/update.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/update/update.go b/pkg/update/update.go index fc7b6ef29b..f27c008464 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -19,6 +19,8 @@ import ( const ( binDir = "bin" + + defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"c5008789635b7ac63228d80eec24edbfb8b3bddfd2121b08456de201ec24df7a"}}]` ) // Updater is responsible for managing update state. @@ -55,7 +57,7 @@ var ( LocalStore: client.MemoryLocalStore(), InsecureTransport: false, Platform: constant.PlatformName, - RootKeys: `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"0994148e5242118d1d6a9a397a3646e0423545a37794a791c28aa39de3b0c523"}}]`, + RootKeys: defaultRootKeys, } ) From 967d812bc2e53f5f3e1d84af345117f7ef67354d Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 8 Feb 2021 15:55:36 -0800 Subject: [PATCH 036/115] Refactor Deb functionality into packaging package --- cmd/package/package.go | 239 +------------------------------------ pkg/packaging/deb.go | 235 ++++++++++++++++++++++++++++++++++++ pkg/packaging/packaging.go | 16 +++ 3 files changed, 254 insertions(+), 236 deletions(-) create mode 100644 pkg/packaging/deb.go create mode 100644 pkg/packaging/packaging.go diff --git a/cmd/package/package.go b/cmd/package/package.go index 19777438ca..b1635e1a5a 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -1,34 +1,18 @@ package main import ( - "bytes" - "io/ioutil" "os" - "path/filepath" - "text/template" "time" - "github.com/fleetdm/orbit/pkg/constant" - "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/filestore" - "github.com/goreleaser/nfpm/v2" - "github.com/goreleaser/nfpm/v2/deb" - "github.com/goreleaser/nfpm/v2/files" + "github.com/fleetdm/orbit/pkg/packaging" "github.com/pkg/errors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" ) -type packageOptions struct { - FleetURL string - EnrollSecret string - StartService bool - Insecure bool -} - func main() { - var opt packageOptions + var opt packaging.Options log.Logger = log.Output( zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, ) @@ -74,227 +58,10 @@ func main() { } } - return buildLinux(opt) + return packaging.BuildDeb(opt) } if err := app.Run(os.Args); err != nil { log.Fatal().Err(err).Msg("package failed") } } - -func buildLinux(opt packageOptions) error { - // Initialize directories - - tmpDir, err := ioutil.TempDir("", "orbit-package") - if err != nil { - return errors.Wrap(err, "failed to create temp dir") - } - defer os.RemoveAll(tmpDir) - log.Debug().Str("path", tmpDir).Msg("created temp dir") - - filesystemRoot := filepath.Join(tmpDir, "filesystem") - if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create filesystem dir") - } - orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") - if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create orbit dir") - } - - // Write files - - if err := writeSystemdUnit(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write systemd unit") - } - - if err := writeEnvFile(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write env file") - } - - postInstallPath := filepath.Join(tmpDir, "postinstall.sh") - if err := writePostInstall(opt, postInstallPath); err != nil { - return errors.Wrap(err, "write postinstall script") - } - - // Initialize autoupdate metadata - - localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) - if err != nil { - return errors.Wrap(err, "failed to create local metadata store") - } - updateOpt := update.DefaultOptions - updateOpt.RootDirectory = orbitRoot - updateOpt.ServerURL = "https://tuf.fleetctl.com" - updateOpt.LocalStore = localStore - updateOpt.Platform = "linux" - - updater, err := update.New(updateOpt) - if err != nil { - return errors.Wrap(err, "failed to init updater") - } - if err := updater.UpdateMetadata(); err != nil { - return errors.Wrap(err, "failed to update metadata") - } - osquerydPath, err := updater.Get("osqueryd", "stable") - if err != nil { - return errors.Wrap(err, "failed to get osqueryd") - } - log.Debug().Str("path", osquerydPath).Msg("got osqueryd") - - // Pick up all file contents - - contents := files.Contents{ - &files.Content{ - Source: filepath.Join(filesystemRoot, "**"), - Destination: "/", - }, - &files.Content{ - Source: "orbit", - Destination: "/var/lib/fleet/orbit/orbit", - FileInfo: &files.ContentFileInfo{ - Mode: constant.DefaultExecutableMode, - }, - }, - &files.Content{ - Source: "/var/lib/fleet/orbit/orbit", - Destination: "/usr/local/bin/orbit", - Type: "symlink", - FileInfo: &files.ContentFileInfo{ - // TODO follow up on nfpm not respecting this - // https://github.com/goreleaser/nfpm/issues/286 - Mode: constant.DefaultExecutableMode | os.ModeSymlink, - }, - }, - } - contents, err = files.ExpandContentGlobs(contents, false) - if err != nil { - return errors.Wrap(err, "glob contents") - } - for _, c := range contents { - log.Debug().Interface("file", c).Msg("added file") - } - - // Build package - - info := &nfpm.Info{ - Name: "orbit-osquery", - Version: "0.0.1", - Description: "Osquery launcher and autoupdater", - Arch: "amd64", - Maintainer: "FleetDM Engineers ", - Homepage: "https://github.com/fleetdm/orbit", - Overridables: nfpm.Overridables{ - Contents: contents, - EmptyFolders: []string{ - "/var/log/osquery", - "/var/log/fleet/orbit", - }, - Scripts: nfpm.Scripts{ - PostInstall: postInstallPath, - }, - }, - } - pkger := deb.Default - filename := pkger.ConventionalFileName(info) - - out, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode) - if err != nil { - return errors.Wrap(err, "open output file") - } - defer out.Close() - - if err := deb.Default.Package(info, out); err != nil { - return errors.Wrap(err, "write deb package") - } - log.Info().Str("path", filename).Msg("wrote deb package") - - return nil -} - -func writeSystemdUnit(optt packageOptions, rootPath string) error { - systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system") - if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create systemd dir") - } - if err := ioutil.WriteFile( - filepath.Join(systemdRoot, "orbit.service"), - []byte(` -[Unit] -Description=Fleet Orbit osquery -After=network.service syslog.service - -[Service] -TimeoutStartSec=0 -EnvironmentFile=/etc/default/orbit -ExecStart=/usr/local/bin/orbit -Restart=on-failure -KillMode=control-group -KillSignal=SIGTERM -CPUQuota=20% - -[Install] -WantedBy=multi-user.target -`), - constant.DefaultFileMode, - ); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - -var envTemplate = template.Must(template.New("env").Parse(` -{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} -{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} -{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} -`)) - -func writeEnvFile(opt packageOptions, rootPath string) error { - envRoot := filepath.Join(rootPath, "etc", "default") - if err := os.MkdirAll(envRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create env dir") - } - - var contents bytes.Buffer - if err := envTemplate.Execute(&contents, opt); err != nil { - return errors.Wrap(err, "execute template") - } - - if err := ioutil.WriteFile( - filepath.Join(envRoot, "orbit"), - contents.Bytes(), - constant.DefaultFileMode, - ); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - -var postInstallTemplate = template.Must(template.New("postinstall").Parse(` -#!/bin/sh - -# Exit on error -set -e - -# If we have a systemd, daemon-reload away now -if [ -x /bin/systemctl ] && pidof systemd ; then - /bin/systemctl daemon-reload 2>/dev/null 2>&1 -{{ if .StartService -}} - /bin/systemctl start orbit.service 2>&1 -{{- end}} -fi -`)) - -func writePostInstall(opt packageOptions, path string) error { - var contents bytes.Buffer - if err := postInstallTemplate.Execute(&contents, opt); err != nil { - return errors.Wrap(err, "execute template") - } - - if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go new file mode 100644 index 0000000000..88a4d25ba3 --- /dev/null +++ b/pkg/packaging/deb.go @@ -0,0 +1,235 @@ +package packaging + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" + "text/template" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" + "github.com/goreleaser/nfpm/v2" + "github.com/goreleaser/nfpm/v2/deb" + "github.com/goreleaser/nfpm/v2/files" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +func BuildDeb(opt Options) error { + // Initialize directories + + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "filesystem") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create filesystem dir") + } + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + // Write files + + if err := writeSystemdUnit(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write systemd unit") + } + + if err := writeEnvFile(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write env file") + } + + postInstallPath := filepath.Join(tmpDir, "postinstall.sh") + if err := writePostInstall(opt, postInstallPath); err != nil { + return errors.Wrap(err, "write postinstall script") + } + + // Initialize autoupdate metadata + + localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) + if err != nil { + return errors.Wrap(err, "failed to create local metadata store") + } + updateOpt := update.DefaultOptions + updateOpt.RootDirectory = orbitRoot + updateOpt.ServerURL = "https://tuf.fleetctl.com" + updateOpt.LocalStore = localStore + updateOpt.Platform = "linux" + + updater, err := update.New(updateOpt) + if err != nil { + return errors.Wrap(err, "failed to init updater") + } + if err := updater.UpdateMetadata(); err != nil { + return errors.Wrap(err, "failed to update metadata") + } + osquerydPath, err := updater.Get("osqueryd", "stable") + if err != nil { + return errors.Wrap(err, "failed to get osqueryd") + } + log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + + // Pick up all file contents + + contents := files.Contents{ + &files.Content{ + Source: filepath.Join(filesystemRoot, "**"), + Destination: "/", + }, + &files.Content{ + Source: "orbit", + Destination: "/var/lib/fleet/orbit/orbit", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode, + }, + }, + &files.Content{ + Source: "/var/lib/fleet/orbit/orbit", + Destination: "/usr/local/bin/orbit", + Type: "symlink", + FileInfo: &files.ContentFileInfo{ + // TODO follow up on nfpm not respecting this + // https://github.com/goreleaser/nfpm/issues/286 + Mode: constant.DefaultExecutableMode | os.ModeSymlink, + }, + }, + } + contents, err = files.ExpandContentGlobs(contents, false) + if err != nil { + return errors.Wrap(err, "glob contents") + } + for _, c := range contents { + log.Debug().Interface("file", c).Msg("added file") + } + + // Build package + + info := &nfpm.Info{ + Name: "orbit-osquery", + Version: "0.0.1", + Description: "Osquery launcher and autoupdater", + Arch: "amd64", + Maintainer: "FleetDM Engineers ", + Homepage: "https://github.com/fleetdm/orbit", + Overridables: nfpm.Overridables{ + Contents: contents, + EmptyFolders: []string{ + "/var/log/osquery", + "/var/log/fleet/orbit", + }, + Scripts: nfpm.Scripts{ + PostInstall: postInstallPath, + }, + }, + } + pkger := deb.Default + filename := pkger.ConventionalFileName(info) + + out, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode) + if err != nil { + return errors.Wrap(err, "open output file") + } + defer out.Close() + + if err := deb.Default.Package(info, out); err != nil { + return errors.Wrap(err, "write deb package") + } + log.Info().Str("path", filename).Msg("wrote deb package") + + return nil +} + +func writeSystemdUnit(opt Options, rootPath string) error { + systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system") + if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create systemd dir") + } + if err := ioutil.WriteFile( + filepath.Join(systemdRoot, "orbit.service"), + []byte(` +[Unit] +Description=Fleet Orbit osquery +After=network.service syslog.service + +[Service] +TimeoutStartSec=0 +EnvironmentFile=/etc/default/orbit +ExecStart=/usr/local/bin/orbit +Restart=on-failure +KillMode=control-group +KillSignal=SIGTERM +CPUQuota=20% + +[Install] +WantedBy=multi-user.target +`), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var envTemplate = template.Must(template.New("env").Parse(` +{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} +{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} +{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} +`)) + +func writeEnvFile(opt Options, rootPath string) error { + envRoot := filepath.Join(rootPath, "etc", "default") + if err := os.MkdirAll(envRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create env dir") + } + + var contents bytes.Buffer + if err := envTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile( + filepath.Join(envRoot, "orbit"), + contents.Bytes(), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var postInstallTemplate = template.Must(template.New("postinstall").Parse(` +#!/bin/sh + +# Exit on error +set -e + +# If we have a systemd, daemon-reload away now +if [ -x /bin/systemctl ] && pidof systemd ; then + /bin/systemctl daemon-reload 2>/dev/null 2>&1 +{{ if .StartService -}} + /bin/systemctl start orbit.service 2>&1 +{{- end}} +fi +`)) + +func writePostInstall(opt Options, path string) error { + var contents bytes.Buffer + if err := postInstallTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go new file mode 100644 index 0000000000..4086f971f2 --- /dev/null +++ b/pkg/packaging/packaging.go @@ -0,0 +1,16 @@ +// package packaging provides tools for buildin Orbit installation packages. +package packaging + +// Options are the configurable options provided for the package. +type Options struct { + // FleetURL is the URL to the Fleet server. + FleetURL string + // EnrollSecret is the enroll secret used to authenticate to the Fleet + // server. + EnrollSecret string + // StartService is a boolean indicating whether to start a system-specific + // background service. + StartService bool + // Insecure enables insecure TLS connections for the generated package. + Insecure bool +} From b0ad96b228d2167ae6d663c4f96c51f3797a63a7 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 8 Feb 2021 19:23:50 -0800 Subject: [PATCH 037/115] Partial progress on macOS packaging --- cmd/package/package.go | 26 +++- pkg/packaging/deb.go | 6 +- pkg/packaging/macos.go | 226 +++++++++++++++++++++++++++++++ pkg/packaging/macos_templates.go | 28 ++++ pkg/packaging/packaging.go | 4 + 5 files changed, 286 insertions(+), 4 deletions(-) create mode 100644 pkg/packaging/macos.go create mode 100644 pkg/packaging/macos_templates.go diff --git a/cmd/package/package.go b/cmd/package/package.go index b1635e1a5a..355a0e274f 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -23,6 +23,11 @@ func main() { app.Usage = "A powered-up, (near) drop-in replacement for osquery" app.Commands = []*cli.Command{} app.Flags = []cli.Flag{ + &cli.StringFlag{ + Name: "type", + Usage: "Type of package to build", + Required: true, + }, &cli.StringFlag{ Name: "enroll-secret", Usage: "Enroll secret for authenticating to Fleet server", @@ -33,6 +38,18 @@ func main() { Usage: "URL (host:port) of Fleet server", Destination: &opt.FleetURL, }, + &cli.StringFlag{ + Name: "identifier", + Usage: "Identifier for package product", + Value: "com.fleetdm.orbit", + Destination: &opt.Identifier, + }, + &cli.StringFlag{ + Name: "version", + Usage: "Version for package product", + Value: "0.0.1", + Destination: &opt.Version, + }, &cli.BoolFlag{ Name: "insecure", Usage: "Disable TLS certificate verification", @@ -58,7 +75,14 @@ func main() { } } - return packaging.BuildDeb(opt) + switch c.String("type") { + case "pkg": + return packaging.BuildPkg(opt) + case "deb": + return packaging.BuildDeb(opt) + default: + return errors.New("type must be one of ('pkg', 'deb')") + } } if err := app.Run(os.Args); err != nil { diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 88a4d25ba3..49e43466dc 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -27,9 +27,9 @@ func BuildDeb(opt Options) error { defer os.RemoveAll(tmpDir) log.Debug().Str("path", tmpDir).Msg("created temp dir") - filesystemRoot := filepath.Join(tmpDir, "filesystem") + filesystemRoot := filepath.Join(tmpDir, "root") if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create filesystem dir") + return errors.Wrap(err, "create root dir") } orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { @@ -113,7 +113,7 @@ func BuildDeb(opt Options) error { info := &nfpm.Info{ Name: "orbit-osquery", - Version: "0.0.1", + Version: opt.Version, Description: "Osquery launcher and autoupdater", Arch: "amd64", Maintainer: "FleetDM Engineers ", diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go new file mode 100644 index 0000000000..294e9e3ccc --- /dev/null +++ b/pkg/packaging/macos.go @@ -0,0 +1,226 @@ +package packaging + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "runtime" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +// See helful docs in http://bomutils.dyndns.org/tutorial.html + +// BuildPkg builds a macOS .pkg. So far this is tested only on macOS but in theory it works with bomutils on +// Linux. +func BuildPkg(opt Options) error { + // Initialize directories + + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + // TODO reenable + //defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "root") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create root dir") + } + // if err := os.MkdirAll( + // filepath.Join(filesystemRoot, "Resources", "en.lproj"), + // constant.DefaultDirMode, + // ); err != nil { + // return errors.Wrap(err, "create resources dir") + // } + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + // Write files + + if err := writePackageInfo(opt, tmpDir); err != nil { + return errors.Wrap(err, "write PackageInfo") + } + if err := writeDistribution(opt, tmpDir); err != nil { + return errors.Wrap(err, "write Distribution") + } + + // Initialize autoupdate metadata + + localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) + if err != nil { + return errors.Wrap(err, "failed to create local metadata store") + } + updateOpt := update.DefaultOptions + updateOpt.RootDirectory = orbitRoot + updateOpt.ServerURL = "https://tuf.fleetctl.com" + updateOpt.LocalStore = localStore + updateOpt.Platform = "macos" + + updater, err := update.New(updateOpt) + if err != nil { + return errors.Wrap(err, "failed to init updater") + } + if err := updater.UpdateMetadata(); err != nil { + return errors.Wrap(err, "failed to update metadata") + } + osquerydPath, err := updater.Get("osqueryd", "stable") + if err != nil { + return errors.Wrap(err, "failed to get osqueryd") + } + log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + + // Build package + if err := xarBom(opt, tmpDir); err != nil { + return errors.Wrap(err, "build pkg") + } + + filename := fmt.Sprintf("orbit-osquery_%s_amd64.pkg", opt.Version) + if err := os.Rename(filepath.Join(tmpDir, "orbit.pkg"), filename); err != nil { + return errors.Wrap(err, "rename pkg") + } + log.Info().Str("path", filename).Msg("wrote pkg package") + + return nil +} + +func writePackageInfo(opt Options, rootPath string) error { + path := filepath.Join(rootPath, "flat", "base.pkg", "PackageInfo") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := macosPackageInfoTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +func writeDistribution(opt Options, rootPath string) error { + path := filepath.Join(rootPath, "flat", "Distribution") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := macosDistributionTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +// xarBom creates the actual .pkg format. It's a xar archive with a BOM (Bill of +// materials?). See http://bomutils.dyndns.org/tutorial.html. +func xarBom(opt Options, rootPath string) error { + // Adapted from BSD licensed + // https://github.com/go-flutter-desktop/hover/blob/v0.46.2/cmd/packaging/darwin-pkg.go + + // Copy payload + payload, err := os.OpenFile(filepath.Join(rootPath, "flat", "base.pkg", "Payload"), os.O_RDWR|os.O_CREATE, 0755) + if err != nil { + return errors.Wrap(err, "open payload") + } + + cmdFind := exec.Command("find", ".") + cmdFind.Dir = filepath.Join(rootPath, "root") + cmdCpio := exec.Command("cpio", "-o", "--format", "odc", "-R", "0:80") + cmdCpio.Dir = filepath.Join(rootPath, "root") + cmdGzip := exec.Command("gzip", "-c") + + // Pipes like this: find | cpio | gzip > Payload + cmdCpio.Stdin, err = cmdFind.StdoutPipe() + if err != nil { + return errors.Wrap(err, "pipe cpio") + } + cmdGzip.Stdin, err = cmdCpio.StdoutPipe() + if err != nil { + return errors.Wrap(err, "pipe gzip") + } + cmdGzip.Stdout = payload + + err = cmdGzip.Start() + if err != nil { + return errors.Wrap(err, "start gzip") + } + err = cmdCpio.Start() + if err != nil { + return errors.Wrap(err, "start cpio") + } + err = cmdFind.Run() + if err != nil { + return errors.Wrap(err, "run find") + } + err = cmdCpio.Wait() + if err != nil { + return errors.Wrap(err, "wait cpio") + } + err = cmdGzip.Wait() + if err != nil { + return errors.Wrap(err, "wait gzip") + } + err = payload.Close() + if err != nil { + return errors.Wrap(err, "close payload") + } + + // Make bom + var cmdMkbom *exec.Cmd + switch runtime.GOOS { + case "darwin": + cmdMkbom = exec.Command("mkbom", filepath.Join(rootPath, "root"), filepath.Join("flat", "base.pkg", "Bom")) + case "linux": + cmdMkbom = exec.Command("mkbom", "-u", "0", "-g", "80", filepath.Join(rootPath, "flat", "root"), filepath.Join("flat", "base.pkg", "Bom")) + } + cmdMkbom.Dir = rootPath + cmdMkbom.Stdout = os.Stdout + cmdMkbom.Stderr = os.Stderr + if err := cmdMkbom.Run(); err != nil { + return errors.Wrap(err, "mkbom") + } + + // List files for xar + var files []string + if err := filepath.Walk(filepath.Join(rootPath, "flat"), func(path string, info os.FileInfo, err error) error { + relativePath, err := filepath.Rel(filepath.Join(rootPath, "flat"), path) + if err != nil { + return err + } + files = append(files, relativePath) + return nil + }); err != nil { + return errors.Wrap(err, "iterate files") + } + + // Make xar + cmdXar := exec.Command("xar", append([]string{"--compression", "none", "-cf", filepath.Join("..", "orbit.pkg")}, files...)...) + cmdXar.Dir = filepath.Join(rootPath, "flat") + cmdXar.Stdout = os.Stdout + cmdXar.Stderr = os.Stderr + + if err := cmdXar.Run(); err != nil { + return errors.Wrap(err, "run xar") + } + + return nil +} diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go new file mode 100644 index 0000000000..415749e115 --- /dev/null +++ b/pkg/packaging/macos_templates.go @@ -0,0 +1,28 @@ +package packaging + +import "text/template" + +// Best reference I could find: +// http://s.sudre.free.fr/Stuff/Ivanhoe/FLAT.html +var macosPackageInfoTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + ` + + + +`)) + +// Reference: +// https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/DistributionDefinitionRef/Chapters/Distribution_XML_Ref.html +var macosDistributionTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + ` + + Orbit + + + + + + + #base.pkg + +`)) diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 4086f971f2..f482085d59 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -8,6 +8,10 @@ type Options struct { // EnrollSecret is the enroll secret used to authenticate to the Fleet // server. EnrollSecret string + // Version is the version number for this package. + Version string + // Identifier is the identifier (eg. com.fleetdm.orbit) for the package product. + Identifier string // StartService is a boolean indicating whether to start a system-specific // background service. StartService bool From be3d70537b9891d3abd22fcd02a48935c203396e Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 16 Feb 2021 18:05:18 -0800 Subject: [PATCH 038/115] macOS packaging works with launchd --- cmd/package/package.go | 8 +- pkg/packaging/deb.go | 30 ++--- pkg/packaging/macos.go | 191 +++++++++++++++++++++---------- pkg/packaging/macos_templates.go | 52 ++++++++- pkg/packaging/packaging.go | 32 ++++++ 5 files changed, 232 insertions(+), 81 deletions(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index 355a0e274f..945334be17 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -55,6 +55,12 @@ func main() { Usage: "Disable TLS certificate verification", Destination: &opt.Insecure, }, + &cli.BoolFlag{ + Name: "service", + Usage: "Install orbit/osquery with a persistence service (launchd, systemd, etc.)", + Value: true, + Destination: &opt.StartService, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", @@ -68,8 +74,6 @@ func main() { } app.Action = func(c *cli.Context) error { if opt.FleetURL != "" || opt.EnrollSecret != "" { - opt.StartService = true - if opt.FleetURL == "" || opt.EnrollSecret == "" { return errors.New("--enroll-secret and --fleet-url must be provided together") } diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 49e43466dc..13b09bc0c5 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -36,21 +36,6 @@ func BuildDeb(opt Options) error { return errors.Wrap(err, "create orbit dir") } - // Write files - - if err := writeSystemdUnit(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write systemd unit") - } - - if err := writeEnvFile(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write env file") - } - - postInstallPath := filepath.Join(tmpDir, "postinstall.sh") - if err := writePostInstall(opt, postInstallPath); err != nil { - return errors.Wrap(err, "write postinstall script") - } - // Initialize autoupdate metadata localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) @@ -76,6 +61,21 @@ func BuildDeb(opt Options) error { } log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + // Write files + + if err := writeSystemdUnit(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write systemd unit") + } + + if err := writeEnvFile(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write env file") + } + + postInstallPath := filepath.Join(tmpDir, "postinstall.sh") + if err := writePostInstall(opt, postInstallPath); err != nil { + return errors.Wrap(err, "write postinstall script") + } + // Pick up all file contents contents := files.Contents{ diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 294e9e3ccc..9c458e74e0 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -27,34 +27,18 @@ func BuildPkg(opt Options) error { if err != nil { return errors.Wrap(err, "failed to create temp dir") } - // TODO reenable - //defer os.RemoveAll(tmpDir) + defer os.RemoveAll(tmpDir) log.Debug().Str("path", tmpDir).Msg("created temp dir") filesystemRoot := filepath.Join(tmpDir, "root") if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create root dir") } - // if err := os.MkdirAll( - // filepath.Join(filesystemRoot, "Resources", "en.lproj"), - // constant.DefaultDirMode, - // ); err != nil { - // return errors.Wrap(err, "create resources dir") - // } orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create orbit dir") } - // Write files - - if err := writePackageInfo(opt, tmpDir); err != nil { - return errors.Wrap(err, "write PackageInfo") - } - if err := writeDistribution(opt, tmpDir); err != nil { - return errors.Wrap(err, "write Distribution") - } - // Initialize autoupdate metadata localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) @@ -80,6 +64,30 @@ func BuildPkg(opt Options) error { } log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + // Write files + + if err := writePackageInfo(opt, tmpDir); err != nil { + return errors.Wrap(err, "write PackageInfo") + } + if err := writeDistribution(opt, tmpDir); err != nil { + return errors.Wrap(err, "write Distribution") + } + if err := writeScripts(opt, tmpDir); err != nil { + return errors.Wrap(err, "write postinstall") + } + if opt.StartService { + if err := writeLaunchd(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write launchd") + } + } + if err := copyFile( + "./orbit", + filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit", "orbit"), + 0755, + ); err != nil { + return errors.Wrap(err, "write orbit") + } + // Build package if err := xarBom(opt, tmpDir); err != nil { return errors.Wrap(err, "build pkg") @@ -95,6 +103,7 @@ func BuildPkg(opt Options) error { } func writePackageInfo(opt Options, rootPath string) error { + // PackageInfo is metadata for the pkg path := filepath.Join(rootPath, "flat", "base.pkg", "PackageInfo") if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "mkdir") @@ -112,7 +121,46 @@ func writePackageInfo(opt Options, rootPath string) error { return nil } +func writeScripts(opt Options, rootPath string) error { + // Postinstall script + path := filepath.Join(rootPath, "scripts", "postinstall") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := macosPostinstallTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), 0744); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +func writeLaunchd(opt Options, rootPath string) error { + // launchd is the service mechanism on macOS + path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := macosLaunchdTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), 0644); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + func writeDistribution(opt Options, rootPath string) error { + // Distribution file is metadata for the pkg path := filepath.Join(rootPath, "flat", "Distribution") if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "mkdir") @@ -136,52 +184,18 @@ func xarBom(opt Options, rootPath string) error { // Adapted from BSD licensed // https://github.com/go-flutter-desktop/hover/blob/v0.46.2/cmd/packaging/darwin-pkg.go - // Copy payload - payload, err := os.OpenFile(filepath.Join(rootPath, "flat", "base.pkg", "Payload"), os.O_RDWR|os.O_CREATE, 0755) - if err != nil { - return errors.Wrap(err, "open payload") + // Copy payload/scripts + if err := cpio( + filepath.Join(rootPath, "root"), + filepath.Join(rootPath, "flat", "base.pkg", "Payload"), + ); err != nil { + return errors.Wrap(err, "cpio Payload") } - - cmdFind := exec.Command("find", ".") - cmdFind.Dir = filepath.Join(rootPath, "root") - cmdCpio := exec.Command("cpio", "-o", "--format", "odc", "-R", "0:80") - cmdCpio.Dir = filepath.Join(rootPath, "root") - cmdGzip := exec.Command("gzip", "-c") - - // Pipes like this: find | cpio | gzip > Payload - cmdCpio.Stdin, err = cmdFind.StdoutPipe() - if err != nil { - return errors.Wrap(err, "pipe cpio") - } - cmdGzip.Stdin, err = cmdCpio.StdoutPipe() - if err != nil { - return errors.Wrap(err, "pipe gzip") - } - cmdGzip.Stdout = payload - - err = cmdGzip.Start() - if err != nil { - return errors.Wrap(err, "start gzip") - } - err = cmdCpio.Start() - if err != nil { - return errors.Wrap(err, "start cpio") - } - err = cmdFind.Run() - if err != nil { - return errors.Wrap(err, "run find") - } - err = cmdCpio.Wait() - if err != nil { - return errors.Wrap(err, "wait cpio") - } - err = cmdGzip.Wait() - if err != nil { - return errors.Wrap(err, "wait gzip") - } - err = payload.Close() - if err != nil { - return errors.Wrap(err, "close payload") + if err := cpio( + filepath.Join(rootPath, "scripts"), + filepath.Join(rootPath, "flat", "base.pkg", "Scripts"), + ); err != nil { + return errors.Wrap(err, "cpio Scripts") } // Make bom @@ -224,3 +238,56 @@ func xarBom(opt Options, rootPath string) error { return nil } + +func cpio(srcPath, dstPath string) error { + // This is the compression routine that is expected for pkg files. + dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE, 0755) + if err != nil { + return errors.Wrap(err, "open dst") + } + defer dst.Close() + + cmdFind := exec.Command("find", ".") + cmdFind.Dir = srcPath + cmdCpio := exec.Command("cpio", "-o", "--format", "odc", "-R", "0:80") + cmdCpio.Dir = srcPath + cmdGzip := exec.Command("gzip", "-c") + + // Pipes like this: find | cpio | gzip > dstPath + cmdCpio.Stdin, err = cmdFind.StdoutPipe() + if err != nil { + return errors.Wrap(err, "pipe cpio") + } + cmdGzip.Stdin, err = cmdCpio.StdoutPipe() + if err != nil { + return errors.Wrap(err, "pipe gzip") + } + cmdGzip.Stdout = dst + + err = cmdGzip.Start() + if err != nil { + return errors.Wrap(err, "start gzip") + } + err = cmdCpio.Start() + if err != nil { + return errors.Wrap(err, "start cpio") + } + err = cmdFind.Run() + if err != nil { + return errors.Wrap(err, "run find") + } + err = cmdCpio.Wait() + if err != nil { + return errors.Wrap(err, "wait cpio") + } + err = cmdGzip.Wait() + if err != nil { + return errors.Wrap(err, "wait gzip") + } + err = dst.Close() + if err != nil { + return errors.Wrap(err, "close dst") + } + + return nil +} diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 415749e115..c70b7fe8f3 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -6,8 +6,11 @@ import "text/template" // http://s.sudre.free.fr/Stuff/Ivanhoe/FLAT.html var macosPackageInfoTemplate = template.Must(template.New("").Option("missingkey=error").Parse( ` - - + + + + + `)) @@ -26,3 +29,48 @@ var macosDistributionTemplate = template.Must(template.New("").Option("missingke #base.pkg `)) + +var macosPostinstallTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + `#!/bin/bash + +ln -sf /var/lib/fleet/orbit/orbit /usr/local/bin/orbit + +{{ if .StartService -}} +launchctl stop com.fleetdm.orbit + +sleep 3 + +launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist +launchctl load /Library/LaunchDaemons/com.fleetdm.orbit.plist +{{- end }} +`)) + +// TODO set Nice? +var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + ` + + + + Label + com.fleetdm.orbit + ProgramArguments + + /var/lib/fleet/orbit/orbit + + StandardOutPath + /var/log/orbit/orbit.stdout.log + StandardErrorPath + /var/log/orbit/orbit.stderr.log + EnvironmentVariables + + {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} + {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} + {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET{{.EnrollSecret}}{{ end }} + + KeepAlive + RunAtLoad + ThrottleInterval + 10 + + +`)) diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index f482085d59..a2d1c84639 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -1,6 +1,14 @@ // package packaging provides tools for buildin Orbit installation packages. package packaging +import ( + "io" + "os" + "path/filepath" + + "github.com/pkg/errors" +) + // Options are the configurable options provided for the package. type Options struct { // FleetURL is the URL to the Fleet server. @@ -18,3 +26,27 @@ type Options struct { // Insecure enables insecure TLS connections for the generated package. Insecure bool } + +func copyFile(srcPath, dstPath string, perm os.FileMode) error { + src, err := os.Open(srcPath) + if err != nil { + return errors.Wrap(err, "open src for copy") + } + defer src.Close() + + if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { + return errors.Wrap(err, "create dst dir for copy") + } + + dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE, perm) + if err != nil { + return errors.Wrap(err, "open dst for copy") + } + defer dst.Close() + + if _, err := io.Copy(dst, src); err != nil { + return errors.Wrap(err, "copy src to dst") + } + + return nil +} From da733d141a045a3abbe25f8db75038bcb719d5e0 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 17 Feb 2021 13:25:56 -0800 Subject: [PATCH 039/115] Code signing and Notarization for macOS --- .gon.hcl | 12 +++++ .goreleaser.yml | 52 +++++++++++++++++++ cmd/package/package.go | 5 ++ go.mod | 2 + go.sum | 30 +++++++++++ pkg/packaging/macos.go | 37 +++++++++++++- pkg/packaging/macos_notarize.go | 88 +++++++++++++++++++++++++++++++++ pkg/packaging/packaging.go | 2 + 8 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 .gon.hcl create mode 100644 .goreleaser.yml create mode 100644 pkg/packaging/macos_notarize.go diff --git a/.gon.hcl b/.gon.hcl new file mode 100644 index 0000000000..9c59a9e151 --- /dev/null +++ b/.gon.hcl @@ -0,0 +1,12 @@ +source = ["./dist/macos_darwin_amd64/orbit"] +bundle_id = "com.fleetdm.orbit" + +apple_id { + username = "zach@fleetdm.com" + password = "@env:AC_PASSWORD" +} + +sign { + application_identity = "D208111AA5D441DE07993F833E1F36F67526F489" +} + diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000000..ce36ff4b0f --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,52 @@ +before: + hooks: + - go mod download + +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + goarch: + - amd64 + dir: ./cmd/orbit/ + binary: orbit + + - id: macos + env: + - CGO_ENABLED=0 + goos: + - darwin + goarch: + - amd64 + dir: ./cmd/orbit/ + binary: orbit + +archives: + - replacements: + darwin: macos + 386: i386 + amd64: x86_64 + +signs: + - signature: "${artifact}_macos.dmg" + ids: + - macos + cmd: gon + args: + - .gon.hcl + artifacts: all + +checksum: + name_template: 'checksums.txt' + +snapshot: + name_template: "{{ .Tag }}-untagged" + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/cmd/package/package.go b/cmd/package/package.go index 945334be17..af7702dbb8 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -61,6 +61,11 @@ func main() { Value: true, Destination: &opt.StartService, }, + &cli.StringFlag{ + Name: "sign-identity", + Usage: "Identity to use for codesigning", + Destination: &opt.SignIdentity, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", diff --git a/go.mod b/go.mod index de873a5b89..18e032ced4 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,10 @@ go 1.15 require ( github.com/dgraph-io/badger/v2 v2.2007.2 + github.com/fatih/color v1.10.0 github.com/goreleaser/nfpm/v2 v2.2.2 github.com/kr/text v0.2.0 // indirect + github.com/mitchellh/gon v0.2.3 github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.20.0 diff --git a/go.sum b/go.sum index 9a8001f3c0..2d29b71e48 100644 --- a/go.sum +++ b/go.sum @@ -39,6 +39,7 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -47,6 +48,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -132,6 +135,7 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= @@ -162,6 +166,7 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -255,11 +260,19 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2 h1:STV8OvzphW1vlhPFxcG8d6OIilzBSKRAoWFJt+Onu10= +github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.6.3 h1:tuulM+WnToeqa05z83YLmKabZxrySOmJAd4mJ+s2Nfg= +github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= @@ -270,6 +283,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= @@ -321,6 +335,7 @@ github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk= github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -340,6 +355,7 @@ github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -357,6 +373,9 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo= +github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -448,8 +467,10 @@ github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0K github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= @@ -489,6 +510,7 @@ github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -551,6 +573,7 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= @@ -561,6 +584,7 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -573,6 +597,7 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190424203555-c05e17bb3b2d/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -607,6 +632,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -658,6 +684,7 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -665,6 +692,7 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= @@ -812,6 +840,8 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= +howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= +howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= mvdan.cc/gofumpt v0.0.0-20200802201014-ab5a8192947d/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws= mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475 h1:5ZmJGYyuTlhdlIpRxSFhdJqkXQweXETFCEaLhRAX3e8= mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0= diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 9c458e74e0..0da08be770 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -93,8 +93,21 @@ func BuildPkg(opt Options) error { return errors.Wrap(err, "build pkg") } + generatedPath := filepath.Join(tmpDir, "orbit.pkg") + + if len(opt.SignIdentity) != 0 { + log.Info().Str("identity", opt.SignIdentity).Msg("productsign package") + if err := signPkg(generatedPath, opt.SignIdentity); err != nil { + return errors.Wrap(err, "productsign") + } + } + + if err := notarizePkg(generatedPath); err != nil { + return err + } + filename := fmt.Sprintf("orbit-osquery_%s_amd64.pkg", opt.Version) - if err := os.Rename(filepath.Join(tmpDir, "orbit.pkg"), filename); err != nil { + if err := os.Rename(generatedPath, filename); err != nil { return errors.Wrap(err, "rename pkg") } log.Info().Str("path", filename).Msg("wrote pkg package") @@ -291,3 +304,25 @@ func cpio(srcPath, dstPath string) error { return nil } + +func signPkg(pkgPath, identity string) error { + var outBuf bytes.Buffer + cmdProductsign := exec.Command( + "productsign", + "--sign", identity, + pkgPath, + pkgPath+".signed", + ) + cmdProductsign.Stdout = &outBuf + cmdProductsign.Stderr = &outBuf + if err := cmdProductsign.Run(); err != nil { + fmt.Println(outBuf.String()) + return errors.Wrap(err, "productsign") + } + + if err := os.Rename(pkgPath+".signed", pkgPath); err != nil { + return errors.Wrap(err, "rename signed") + } + + return nil +} diff --git a/pkg/packaging/macos_notarize.go b/pkg/packaging/macos_notarize.go new file mode 100644 index 0000000000..a109239472 --- /dev/null +++ b/pkg/packaging/macos_notarize.go @@ -0,0 +1,88 @@ +package packaging + +import ( + "context" + "os" + "sync" + + "github.com/fatih/color" + "github.com/mitchellh/gon/notarize" + "github.com/mitchellh/gon/staple" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +func notarizePkg(pkgPath string) error { + username, ok := os.LookupEnv("AC_USERNAME") + if !ok { + return errors.New("AC_USERNAME must be set in environment") + } + + password, ok := os.LookupEnv("AC_PASSWORD") + if !ok { + return errors.New("AC_PASSWORD must be set in environment") + } + + info, err := notarize.Notarize( + context.Background(), + ¬arize.Options{ + File: pkgPath, + BundleId: "com.fleetdm.orbit", + Username: username, + Password: password, + Status: &statusHuman{ + Lock: &sync.Mutex{}, + }, + }, + ) + if err != nil { + return errors.Wrap(err, "notarize") + } + + log.Info().Str("logs", info.LogFileURL).Msg("notarization completed") + + if err := staple.Staple(context.Background(), &staple.Options{File: pkgPath}); err != nil { + return errors.Wrap(err, "staple notarization") + } + + return nil +} + +// This status plugin copied from +// https://github.com/mitchellh/gon/blob/v0.2.3/cmd/gon/status_human.go since it +// is not exposed from the gon library. + +// statusHuman implements notarize.Status and outputs information to +// the CLI for human consumption. +type statusHuman struct { + Prefix string + Lock *sync.Mutex + + lastStatus string +} + +func (s *statusHuman) Submitting() { + s.Lock.Lock() + defer s.Lock.Unlock() + + color.New().Fprintf(os.Stdout, " %sSubmitting file for notarization...\n", s.Prefix) +} + +func (s *statusHuman) Submitted(uuid string) { + s.Lock.Lock() + defer s.Lock.Unlock() + + color.New().Fprintf(os.Stdout, " %sSubmitted. Request UUID: %s\n", s.Prefix, uuid) + color.New().Fprintf( + os.Stdout, " %sWaiting for results from Apple. This can take minutes to hours.\n", s.Prefix) +} + +func (s *statusHuman) Status(info notarize.Info) { + s.Lock.Lock() + defer s.Lock.Unlock() + + if info.Status != s.lastStatus { + s.lastStatus = info.Status + color.New().Fprintf(os.Stdout, " %sStatus: %s\n", s.Prefix, info.Status) + } +} diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index a2d1c84639..2c37ac5e35 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -25,6 +25,8 @@ type Options struct { StartService bool // Insecure enables insecure TLS connections for the generated package. Insecure bool + // SignIdentity is the codesigning identity to use (only macOS at this time) + SignIdentity string } func copyFile(srcPath, dstPath string, perm os.FileMode) error { From c1dc28d32cd09b099e438addfd854ed583accf65 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 17 Feb 2021 13:39:25 -0800 Subject: [PATCH 040/115] Fix lint --- pkg/packaging/macos.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 0da08be770..a0afff82ee 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -228,14 +228,18 @@ func xarBom(opt Options, rootPath string) error { // List files for xar var files []string - if err := filepath.Walk(filepath.Join(rootPath, "flat"), func(path string, info os.FileInfo, err error) error { - relativePath, err := filepath.Rel(filepath.Join(rootPath, "flat"), path) - if err != nil { - return err - } - files = append(files, relativePath) - return nil - }); err != nil { + err := filepath.Walk( + filepath.Join(rootPath, "flat"), + func(path string, info os.FileInfo, _ error) error { + relativePath, err := filepath.Rel(filepath.Join(rootPath, "flat"), path) + if err != nil { + return err + } + files = append(files, relativePath) + return nil + }, + ) + if err != nil { return errors.Wrap(err, "iterate files") } From bc58206b9653ed55c0c042f46280ff91e414c7e4 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 17 Feb 2021 16:22:03 -0800 Subject: [PATCH 041/115] Make macOS notarization optional for packaging --- cmd/package/package.go | 5 +++++ pkg/packaging/macos.go | 6 ++++-- pkg/packaging/packaging.go | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index af7702dbb8..0ba6ef05bb 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -66,6 +66,11 @@ func main() { Usage: "Identity to use for codesigning", Destination: &opt.SignIdentity, }, + &cli.BoolFlag{ + Name: "notarize", + Usage: "Whether to notarize macOS packages", + Destination: &opt.Notarize, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index a0afff82ee..59dcebb532 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -102,8 +102,10 @@ func BuildPkg(opt Options) error { } } - if err := notarizePkg(generatedPath); err != nil { - return err + if opt.Notarize { + if err := notarizePkg(generatedPath); err != nil { + return err + } } filename := fmt.Sprintf("orbit-osquery_%s_amd64.pkg", opt.Version) diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 2c37ac5e35..2994a4db9f 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -27,6 +27,8 @@ type Options struct { Insecure bool // SignIdentity is the codesigning identity to use (only macOS at this time) SignIdentity string + // Notarize sets whether macOS packages should be Notarized. + Notarize bool } func copyFile(srcPath, dstPath string, perm os.FileMode) error { From d97c4972f3edea74075fdab081384982f1162ef4 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 17 Feb 2021 16:22:27 -0800 Subject: [PATCH 042/115] Allow enroll secret to read from file This is needed to be able to secure the enroll secret while maintaining standard file permissions for the macOS launchd plist. Also moves the default directory from /var/lib/fleet/orbit to /var/lib/orbit. --- cmd/orbit/orbit.go | 28 ++++++++++++++++++++++++++-- go.mod | 1 - pkg/packaging/deb.go | 8 ++++---- pkg/packaging/macos.go | 25 +++++++++++++++++++------ pkg/packaging/macos_templates.go | 6 +++--- pkg/update/update.go | 2 +- 6 files changed, 53 insertions(+), 17 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index eb31e759ba..d9f39eb693 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "time" "github.com/fleetdm/orbit/pkg/constant" @@ -24,7 +25,7 @@ import ( const ( tufURL = "https://tuf.fleetctl.com" certPath = "/tmp/fleet.pem" - defaultRootDir = "/var/lib/fleet/orbit" + defaultRootDir = "/var/lib/orbit" ) func main() { @@ -67,6 +68,11 @@ func main() { Usage: "Enroll secret for authenticating to Fleet server", EnvVars: []string{"ORBIT_ENROLL_SECRET"}, }, + &cli.StringFlag{ + Name: "enroll-secret-path", + Usage: "Path to file containing enroll secret", + EnvVars: []string{"ORBIT_ENROLL_SECRET_PATH"}, + }, &cli.StringFlag{ Name: "osquery-version", Usage: "Version of osquery to use", @@ -84,6 +90,19 @@ func main() { zerolog.SetGlobalLevel(zerolog.DebugLevel) } + if c.String("enroll-secret-path") != "" { + if c.String("enroll-secret") != "" { + return errors.New("enroll-secret and enroll-secret-path may not be specified together") + } + + b, err := ioutil.ReadFile(c.String("enroll-secret-path")) + if err != nil { + return errors.Wrap(err, "read enroll secret file") + } + + c.Set("enroll-secret", strings.TrimSpace(string(b))) + } + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "initialize root dir") } @@ -164,7 +183,8 @@ func main() { ) } - if enrollSecret := c.String("enroll-secret"); enrollSecret != "" { + enrollSecret := c.String("enroll-secret") + if enrollSecret != "" { options = append(options, osquery.WithEnv([]string{"ENROLL_SECRET=" + enrollSecret}), osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), @@ -172,6 +192,10 @@ func main() { } if fleetURL != "" { + if enrollSecret == "" { + return errors.New("enroll secret must be specified to connect to Fleet server") + } + options = append(options, osquery.WithFlags(osquery.FleetFlags(fleetURL)), ) diff --git a/go.mod b/go.mod index 18e032ced4..27bad1d963 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,6 @@ require ( github.com/rs/zerolog v1.20.0 github.com/stretchr/testify v1.6.1 github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 - github.com/urfave/cli v1.22.5 github.com/urfave/cli/v2 v2.3.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect ) diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 13b09bc0c5..d2b600cf6e 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -31,7 +31,7 @@ func BuildDeb(opt Options) error { if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create root dir") } - orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "orbit") if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create orbit dir") } @@ -85,13 +85,13 @@ func BuildDeb(opt Options) error { }, &files.Content{ Source: "orbit", - Destination: "/var/lib/fleet/orbit/orbit", + Destination: "/var/lib/orbit/orbit", FileInfo: &files.ContentFileInfo{ Mode: constant.DefaultExecutableMode, }, }, &files.Content{ - Source: "/var/lib/fleet/orbit/orbit", + Source: "/var/lib/orbit/orbit", Destination: "/usr/local/bin/orbit", Type: "symlink", FileInfo: &files.ContentFileInfo{ @@ -122,7 +122,7 @@ func BuildDeb(opt Options) error { Contents: contents, EmptyFolders: []string{ "/var/log/osquery", - "/var/log/fleet/orbit", + "/var/log/orbit", }, Scripts: nfpm.Scripts{ PostInstall: postInstallPath, diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 59dcebb532..2481d55a0b 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -34,7 +34,7 @@ func BuildPkg(opt Options) error { if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create root dir") } - orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit") + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "orbit") if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { return errors.Wrap(err, "create orbit dir") } @@ -75,16 +75,15 @@ func BuildPkg(opt Options) error { if err := writeScripts(opt, tmpDir); err != nil { return errors.Wrap(err, "write postinstall") } + if err := writeSecret(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write enroll secret") + } if opt.StartService { if err := writeLaunchd(opt, filesystemRoot); err != nil { return errors.Wrap(err, "write launchd") } } - if err := copyFile( - "./orbit", - filepath.Join(filesystemRoot, "var", "lib", "fleet", "orbit", "orbit"), - 0755, - ); err != nil { + if err := copyFile("./orbit", filepath.Join(orbitRoot, "orbit"), 0755); err != nil { return errors.Wrap(err, "write orbit") } @@ -155,6 +154,20 @@ func writeScripts(opt Options, rootPath string) error { return nil } +func writeSecret(opt Options, orbitRoot string) error { + // Enroll secret + path := filepath.Join(orbitRoot, "secret") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + func writeLaunchd(opt Options, rootPath string) error { // launchd is the service mechanism on macOS path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist") diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index c70b7fe8f3..8f656b4959 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -33,7 +33,7 @@ var macosDistributionTemplate = template.Must(template.New("").Option("missingke var macosPostinstallTemplate = template.Must(template.New("").Option("missingkey=error").Parse( `#!/bin/bash -ln -sf /var/lib/fleet/orbit/orbit /usr/local/bin/orbit +ln -sf /var/lib/orbit/orbit /usr/local/bin/orbit {{ if .StartService -}} launchctl stop com.fleetdm.orbit @@ -55,7 +55,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err com.fleetdm.orbit ProgramArguments - /var/lib/fleet/orbit/orbit + /var/lib/orbit/orbit StandardOutPath /var/log/orbit/orbit.stdout.log @@ -65,7 +65,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} - {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET{{.EnrollSecret}}{{ end }} + {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} KeepAlive RunAtLoad diff --git a/pkg/update/update.go b/pkg/update/update.go index f27c008464..c8e5ad216b 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -52,7 +52,7 @@ var ( // DefaultOptions are the default options to use when creating an update // client. DefaultOptions = Options{ - RootDirectory: "/var/fleet", + RootDirectory: "/var/lib/orbit", ServerURL: "https://tuf.fleetctl.com", LocalStore: client.MemoryLocalStore(), InsecureTransport: false, From c4a5785427f1ffdf726b49ac6d9e77bae4d76e69 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Sat, 20 Feb 2021 11:24:44 -0800 Subject: [PATCH 043/115] Cleanup and rename version to channel --- cmd/orbit/orbit.go | 2 ++ pkg/osquery/osquery.go | 2 -- pkg/update/hash.go | 12 +++++++++--- pkg/update/update.go | 25 +++++++++++++------------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index d9f39eb693..f532938635 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -201,6 +201,8 @@ func main() { ) } + options = append(options, osquery.WithFlags([]string{"--force"})) + if c.Bool("debug") { options = append(options, osquery.WithFlags([]string{"--verbose", "--tls_dump"}), diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 985d4af28d..e8a8af5847 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -64,8 +64,6 @@ func WithEnv(env []string) func(*Runner) error { func WithShell() func(*Runner) error { return func(r *Runner) error { r.cmd.Args = append(r.cmd.Args, "-S") - r.cmd.Stdout = os.Stdout - r.cmd.Stderr = os.Stderr r.cmd.Stdin = os.Stdin return nil } diff --git a/pkg/update/hash.go b/pkg/update/hash.go index cd7fc69648..ada9f040d2 100644 --- a/pkg/update/hash.go +++ b/pkg/update/hash.go @@ -38,12 +38,18 @@ func CheckFileHash(meta *data.TargetFileMeta, localPath string) error { // selectHashFunction returns the first matching hash function and expected // hash, otherwise returning an error if not matching hash can be found. +// +// SHA512 is preferred, and SHA256 is returned if 512 is not available. + func selectHashFunction(meta *data.TargetFileMeta) (hash.Hash, []byte, error) { for hashName, hashVal := range meta.Hashes { - switch hashName { - case "sha512": + if hashName == "sha512" { return sha512.New(), hashVal, nil - case "sha256": + } + } + + for hashName, hashVal := range meta.Hashes { + if hashName == "sha256" { return sha256.New(), hashVal, nil } } diff --git a/pkg/update/update.go b/pkg/update/update.go index c8e5ad216b..6dd63b4d1c 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -115,20 +115,20 @@ func (u *Updater) UpdateMetadata() error { return nil } -func (u *Updater) RepoPath(name, version string) string { - return path.Join(name, u.opt.Platform, version, name+constant.ExecutableExtension(u.opt.Platform)) +func (u *Updater) RepoPath(name, channel string) string { + return path.Join(name, u.opt.Platform, channel, name+constant.ExecutableExtension(u.opt.Platform)) } -func (u *Updater) LocalPath(name, version string) string { - return u.pathFromRoot(filepath.Join(binDir, name, u.opt.Platform, version, name+constant.ExecutableExtension(u.opt.Platform))) +func (u *Updater) LocalPath(name, channel string) string { + return u.pathFromRoot(filepath.Join(binDir, name, u.opt.Platform, channel, name+constant.ExecutableExtension(u.opt.Platform))) } // Lookup looks up the provided target in the local target metadata. This should // be called after UpdateMetadata. -func (u *Updater) Lookup(name, version string) (*data.TargetFileMeta, error) { - target, err := u.client.Target(u.RepoPath(name, version)) +func (u *Updater) Lookup(name, channel string) (*data.TargetFileMeta, error) { + target, err := u.client.Target(u.RepoPath(name, channel)) if err != nil { - return nil, errors.Wrapf(err, "lookup target %v", target) + return nil, errors.Wrapf(err, "lookup %s@%s", name, channel) } return &target, nil @@ -146,9 +146,9 @@ func (u *Updater) Targets() (data.TargetFiles, error) { // Get returns the local path to the specified target. The target is downloaded // if it does not yet exist locally or the hash does not match. -func (u *Updater) Get(name, version string) (string, error) { - localPath := u.LocalPath(name, version) - repoPath := u.RepoPath(name, version) +func (u *Updater) Get(name, channel string) (string, error) { + localPath := u.LocalPath(name, channel) + repoPath := u.RepoPath(name, channel) stat, err := os.Stat(localPath) if err != nil { log.Debug().Err(err).Msg("stat file") @@ -158,7 +158,7 @@ func (u *Updater) Get(name, version string) (string, error) { return "", errors.Errorf("expected %s to be regular file", localPath) } - meta, err := u.Lookup(name, version) + meta, err := u.Lookup(name, channel) if err != nil { return "", err } @@ -168,7 +168,7 @@ func (u *Updater) Get(name, version string) (string, error) { return localPath, u.Download(repoPath, localPath) } - log.Debug().Str("path", localPath).Msg("found expected version locally") + log.Debug().Str("path", localPath).Msg("found expected channel locally") return localPath, nil } @@ -189,6 +189,7 @@ func (u *Updater) Download(repoPath, localPath string) error { return errors.Wrap(err, "initialize download dir") } + // The go-tuf client handles checking of max size and hash. if err := u.client.Download(repoPath, &fileDestination{tmp}); err != nil { return errors.Wrapf(err, "download target %s", repoPath) } From 736dbbc6005bc40eaba536ed078c2e8b80824688 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 14:52:21 -0800 Subject: [PATCH 044/115] Add update runner Runner handles watching for updates in the background and exiting the Orbit process after a successful update. --- cmd/orbit/orbit.go | 12 +++ pkg/packaging/macos.go | 6 +- pkg/packaging/macos_templates.go | 7 +- pkg/update/runner.go | 155 +++++++++++++++++++++++++++++++ pkg/update/update.go | 32 +++---- 5 files changed, 194 insertions(+), 18 deletions(-) create mode 100644 pkg/update/runner.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index f532938635..c042cf5978 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -141,6 +141,18 @@ func main() { } var g run.Group + + updateRunner, err := update.NewRunner(updater, update.RunnerOptions{ + CheckInterval: 10 * time.Second, + Targets: map[string]string{ + "osqueryd": c.String("osquery-version"), + }, + }) + if err != nil { + return err + } + g.Add(updateRunner.Execute, updateRunner.Interrupt) + var options []func(*osquery.Runner) error options = append(options, osquery.WithDataPath(c.String("root-dir"))) diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 2481d55a0b..304af9cd2d 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -83,7 +83,11 @@ func BuildPkg(opt Options) error { return errors.Wrap(err, "write launchd") } } - if err := copyFile("./orbit", filepath.Join(orbitRoot, "orbit"), 0755); err != nil { + if err := copyFile( + "./orbit", + filepath.Join(orbitRoot, "bin", "orbit", "macos", "current", "orbit"), + 0755, + ); err != nil { return errors.Wrap(err, "write orbit") } diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 8f656b4959..ebf451a850 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -46,6 +46,11 @@ launchctl load /Library/LaunchDaemons/com.fleetdm.orbit.plist `)) // TODO set Nice? +// +//Note it's important not to start the orbit binary in +// `/usr/local/bin/orbit` because this is a path that users usually have write +// access to, and running that binary with launchd can become a privilege +// escalation vector. var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=error").Parse( ` @@ -55,7 +60,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err com.fleetdm.orbit ProgramArguments - /var/lib/orbit/orbit + /var/lib/orbit/bin/orbit/macos/current/orbit StandardOutPath /var/log/orbit/orbit.stdout.log diff --git a/pkg/update/runner.go b/pkg/update/runner.go new file mode 100644 index 0000000000..489e9330d6 --- /dev/null +++ b/pkg/update/runner.go @@ -0,0 +1,155 @@ +package update + +import ( + "bytes" + "os" + "path/filepath" + "time" + + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +// RunnerOptions is options provided for the update runner. +type RunnerOptions struct { + // CheckInterval is the interval to check for updates. + CheckInterval time.Duration + // Targets is the names of the artifacts to watch for updates. + Targets map[string]string +} + +// Runner is a specialized runner for the updater. It is designed with Execute and +// Interrupt functions to be compatible with oklog/run. +type Runner struct { + client *Updater + opt RunnerOptions + cancel chan struct{} + hashCache map[string][]byte +} + +// NewRunner creates a new runner with the provided options. The runner must be +// started with Execute. +func NewRunner(client *Updater, opt RunnerOptions) (*Runner, error) { + if opt.CheckInterval <= 0 { + return nil, errors.New("Runner must be configured with interval greater than 0") + } + if len(opt.Targets) == 0 { + return nil, errors.New("Runner must have nonempty subscriptions") + } + + // Initialize hash cache + cache := make(map[string][]byte) + for target, channel := range opt.Targets { + meta, err := client.Lookup(target, channel) + if err != nil { + return nil, errors.Wrap(err, "initialize update cache") + } + + _, hash, err := selectHashFunction(meta) + if err != nil { + return nil, errors.Wrap(err, "select hash for cache") + } + cache[target] = hash + } + + return &Runner{ + client: client, + opt: opt, + + // chan gets capacity of 1 so we don't end up hung if Interrupt is + // called after Execute has already returned. + cancel: make(chan struct{}, 1), + hashCache: cache, + }, nil +} + +// Execute begins a loop checking for updates. +func (r *Runner) Execute() error { + ticker := time.NewTicker(r.opt.CheckInterval) + defer ticker.Stop() + + // Run until cancel or returning an error + for { + select { + case <-r.cancel: + return nil + + case <-ticker.C: + // On each tick, check for updates + didUpdate, err := r.updateAction() + if err != nil { + log.Info().Err(err).Msg("update failed") + } + if didUpdate { + log.Info().Msg("exiting due to successful update") + return nil + } + } + } +} + +func (r *Runner) updateAction() (bool, error) { + var didUpdate bool + if err := r.client.UpdateMetadata(); err != nil { + // Consider this a non-fatal error since it will be common to be offline + // or otherwise unable to retrieve the metadata. + return didUpdate, errors.Wrap(err, "update metadata") + } + + for target, channel := range r.opt.Targets { + meta, err := r.client.Lookup(target, channel) + if err != nil { + return didUpdate, errors.Wrapf(err, "lookup failed") + } + + // Check whether the hash has changed + _, hash, err := selectHashFunction(meta) + if err != nil { + return didUpdate, errors.Wrap(err, "select hash for cache") + } + + if !bytes.Equal(r.hashCache[target], hash) { + // Update detected + log.Info().Str("target", target).Str("channel", channel).Msg("update detected") + if err := r.updateTarget(target, channel); err != nil { + return didUpdate, errors.Wrapf(err, "update %s@%s", target, channel) + } + log.Info().Str("target", target).Str("channel", channel).Msg("update completed") + didUpdate = true + } else { + log.Debug().Str("target", target).Str("channel", channel).Msg("no update") + } + } + + return didUpdate, nil +} + +func (r *Runner) updateTarget(target, channel string) error { + path, err := r.client.Get(target, channel) + if err != nil { + return errors.Wrap(err, "get binary") + } + + // Replace file/link + currentPath := r.client.LocalPath(target, "current") + if err := os.Remove(currentPath); err != nil && !os.IsNotExist(err) { + return errors.Wrap(err, "remove old current") + } + + if err := os.MkdirAll(filepath.Dir(currentPath), 0755); err != nil { + return errors.Wrap(err, "mkdir for symlink") + } + if err := os.Symlink(path, currentPath); err != nil { + return errors.Wrap(err, "symlink current") + } + + // TODO signal a restart? + + return nil +} + +func (r *Runner) Interrupt(err error) { + r.cancel <- struct{}{} + log.Debug().Msg("interrupt updater") + return +} diff --git a/pkg/update/update.go b/pkg/update/update.go index 6dd63b4d1c..2fd31de1e2 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -20,7 +20,7 @@ import ( const ( binDir = "bin" - defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"c5008789635b7ac63228d80eec24edbfb8b3bddfd2121b08456de201ec24df7a"}}]` + defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"037b475337c1acdafe20cff4fee6308209bc4ba23a2439a1f7be85131794cae1"}}]` ) // Updater is responsible for managing update state. @@ -43,7 +43,7 @@ type Options struct { RootKeys string // LocalStore is the local metadata store. LocalStore client.LocalStore - // Platform is the name of the platform to update for. In the default + // Platform is the target of the platform to update for. In the default // options this is the current platform. Platform string } @@ -115,23 +115,23 @@ func (u *Updater) UpdateMetadata() error { return nil } -func (u *Updater) RepoPath(name, channel string) string { - return path.Join(name, u.opt.Platform, channel, name+constant.ExecutableExtension(u.opt.Platform)) +func (u *Updater) RepoPath(target, channel string) string { + return path.Join(target, u.opt.Platform, channel, target+constant.ExecutableExtension(u.opt.Platform)) } -func (u *Updater) LocalPath(name, channel string) string { - return u.pathFromRoot(filepath.Join(binDir, name, u.opt.Platform, channel, name+constant.ExecutableExtension(u.opt.Platform))) +func (u *Updater) LocalPath(target, channel string) string { + return u.pathFromRoot(filepath.Join(binDir, target, u.opt.Platform, channel, target+constant.ExecutableExtension(u.opt.Platform))) } // Lookup looks up the provided target in the local target metadata. This should // be called after UpdateMetadata. -func (u *Updater) Lookup(name, channel string) (*data.TargetFileMeta, error) { - target, err := u.client.Target(u.RepoPath(name, channel)) +func (u *Updater) Lookup(target, channel string) (*data.TargetFileMeta, error) { + t, err := u.client.Target(u.RepoPath(target, channel)) if err != nil { - return nil, errors.Wrapf(err, "lookup %s@%s", name, channel) + return nil, errors.Wrapf(err, "lookup %s@%s", target, channel) } - return &target, nil + return &t, nil } // Targets gets all of the known targets @@ -146,9 +146,9 @@ func (u *Updater) Targets() (data.TargetFiles, error) { // Get returns the local path to the specified target. The target is downloaded // if it does not yet exist locally or the hash does not match. -func (u *Updater) Get(name, channel string) (string, error) { - localPath := u.LocalPath(name, channel) - repoPath := u.RepoPath(name, channel) +func (u *Updater) Get(target, channel string) (string, error) { + localPath := u.LocalPath(target, channel) + repoPath := u.RepoPath(target, channel) stat, err := os.Stat(localPath) if err != nil { log.Debug().Err(err).Msg("stat file") @@ -158,17 +158,17 @@ func (u *Updater) Get(name, channel string) (string, error) { return "", errors.Errorf("expected %s to be regular file", localPath) } - meta, err := u.Lookup(name, channel) + meta, err := u.Lookup(target, channel) if err != nil { return "", err } if err := CheckFileHash(meta, localPath); err != nil { - log.Debug().Err(err).Msg("will redownload due to error checking hash") + log.Debug().Err(err).Msg("will redownload") return localPath, u.Download(repoPath, localPath) } - log.Debug().Str("path", localPath).Msg("found expected channel locally") + log.Debug().Str("path", localPath).Str("target", target).Str("channel", channel).Msg("found expected target locally") return localPath, nil } From 888056bc62597cef6acadee8f70f82adc511e067 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 14:53:13 -0800 Subject: [PATCH 045/115] Add macos cleanup script Cleans up an install of Orbit on macOS. --- tools/cleanup/cleanup_macos.sh | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 tools/cleanup/cleanup_macos.sh diff --git a/tools/cleanup/cleanup_macos.sh b/tools/cleanup/cleanup_macos.sh new file mode 100755 index 0000000000..8e735a17b2 --- /dev/null +++ b/tools/cleanup/cleanup_macos.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +sudo launchctl stop com.fleetdm.orbit +sudo launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist + +sudo rm -rf /Library/LaunchDaemons/com.fleetdm.orbit.plist /var/lib/orbit/ /usr/local/bin/orbit From a6ab68b3938c94d79092231d28cb329998403b96 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 16:39:48 -0800 Subject: [PATCH 046/115] Initial README --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c6c73c8293 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +Fleet logo, landscape, dark text, transparent background + +# Orbit osquery + +Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autoupdater. With Orbit, it's easy to deploy osquery, manage configurations, and stay up to date. Orbit eases the deployment of osquery connected with a [Fleet server](https://github.com/fleetdm/fleet), and is a (near) drop-in replacement for osquery in a variety of deployment scenarios. + +## Capabilities + +| Capability | Status | +| ------------------------------------ | ------ | +| Secure autoupdate for osquery | ✅ | +| Secure autoupdate for Orbit | ✅ | +| Full osquery flag customization | ✅ | +| Package tooling for macOS `.pkg` | ✅ | +| Package tooling for Linux `.deb` | ✅ | +| Package tooling for Linux `.rpm` | 🔜 | +| Package tooling for Windows `.msi` | 🔜 | +| Manage/update osquery extensions | 🔜 | +| Manage cgroups for Linux performance | 🔜 | + +## FAQs + +### How does Orbit compare with Kolide Launcher? + +Orbit is inspired by the success of [Kolide Launcher](https://github.com/kolide/launcher), and approaches a similar problem domain with new strategies informed by the challenges encountered in real world deployments. + +- Both Orbit and Launcher use [The Update Framework](https://theupdateframework.com/) specification for managing updates. Orbit utilizes the official [go-tuf](https://github.com/theupdateframework/go-tuf) library, while Launcher has it's own implementation of the specification. +- Orbit can be deployed as a (near) drop-in replacement for osquery, supporting full customization of the osquery flags. Launcher heavily manages the osquery flags making deployment outside of Fleet or Kolide's SaaS difficult. +- Orbit prefers the battle-tested plugins of osquery. Orbit uses the built-in logging, configuration, and live query plugins, while Launcher uses custom implementations. +- Orbit prefers the built-in osquery remote APIs. Launcher utilizes a custom gRPC API that has led to issues with character encoding, load balancers/proxies, and request size limits. +- Orbit encourages use of the osquery performance Watchdog, while Launcher disables the Watchdog. + +Additionally, Orbit aims to tackle problems out of scope for Launcher: + +- Configure updates via release channels, providing more granular control over agent versioning. +- Support for deploying and updating osquery extensions (🔜). +- Manage osquery versions and startup flags from a remote (Fleet) server (🔜). +- Further control of osquery performance via cgroups (🔜). + +### Is Orbit Free? + +Yes! Orbit is licensed under an MIT license and all uses are encouraged. + +## Community + +#### Chat + +Please join us in the #fleet channel on [osquery Slack](https://osquery.slack.com/join/shared_invite/zt-h29zm0gk-s2DBtGUTW4CFel0f0IjTEw#/). + +Banner featuring a futuristic cloud city with the Fleet logo From a96dee0f24d009c434e58ad1907d9a3947d6dc17 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 16:51:58 -0800 Subject: [PATCH 047/115] Add TODO sections in readme --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index c6c73c8293..0dee28764a 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,14 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autou | Manage/update osquery extensions | 🔜 | | Manage cgroups for Linux performance | 🔜 | +## Usage + +TODO + +## Packaging + +TODO + ## FAQs ### How does Orbit compare with Kolide Launcher? From 8120c2742e2c093e8178b4610152e5eaa82fc7f1 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 16:53:11 -0800 Subject: [PATCH 048/115] Add MIT license --- LICENSE | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..0ba0ae2c92 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2021-present Fleet Device Management Inc + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 44a29b86ed93a156b5880351446d019bc7ebf783 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 16:57:31 -0800 Subject: [PATCH 049/115] Cleaning and fix lint --- cmd/orbit/orbit.go | 4 +++- pkg/packaging/deb.go | 4 ++-- pkg/update/runner.go | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index c042cf5978..dca17bc6d7 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -100,7 +100,9 @@ func main() { return errors.Wrap(err, "read enroll secret file") } - c.Set("enroll-secret", strings.TrimSpace(string(b))) + if err := c.Set("enroll-secret", strings.TrimSpace(string(b))); err != nil { + return errors.Wrap(err, "set enroll secret from file") + } } if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index d2b600cf6e..0476348922 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -114,9 +114,9 @@ func BuildDeb(opt Options) error { info := &nfpm.Info{ Name: "orbit-osquery", Version: opt.Version, - Description: "Osquery launcher and autoupdater", + Description: "Orbit osquery -- runtime and autoupdater by Fleet", Arch: "amd64", - Maintainer: "FleetDM Engineers ", + Maintainer: "Fleet Engineers ", Homepage: "https://github.com/fleetdm/orbit", Overridables: nfpm.Overridables{ Contents: contents, diff --git a/pkg/update/runner.go b/pkg/update/runner.go index 489e9330d6..ac90cc4bdd 100644 --- a/pkg/update/runner.go +++ b/pkg/update/runner.go @@ -151,5 +151,4 @@ func (r *Runner) updateTarget(target, channel string) error { func (r *Runner) Interrupt(err error) { r.cancel <- struct{}{} log.Debug().Msg("interrupt updater") - return } From 212f8c34253325c39bf774244bcf2118fa3d11a6 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Feb 2021 16:58:30 -0800 Subject: [PATCH 050/115] Rename build-go workflow --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 9815a6697f..366e2852eb 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,4 +1,4 @@ -name: Go +name: build-go on: push: From 47d68c4ca018e759e5a1322a842165399b43b671 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 24 Feb 2021 11:11:43 -0800 Subject: [PATCH 051/115] Allow TLS proxy to handle wider range of input Supports URL with and without https:// prefix. --- cmd/orbit/orbit.go | 2 ++ pkg/insecure/proxy.go | 23 +++++++++++++++--- pkg/insecure/proxy_test.go | 50 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index dca17bc6d7..3c9e93cee0 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -223,6 +223,7 @@ func main() { ) } + // Handle additional args after -- options = append(options, osquery.WithFlags([]string(c.Args().Slice()))) // Create an osquery runner with the provided options @@ -311,6 +312,7 @@ var shellCommand = &cli.Command{ r, _ := osquery.NewRunner( osquerydPath, osquery.WithShell(), + // Handle additional args after -- osquery.WithFlags([]string(c.Args().Slice())), osquery.WithDataPath(c.String("root-dir")), ) diff --git a/pkg/insecure/proxy.go b/pkg/insecure/proxy.go index 605f6ca4bc..804e2df49d 100644 --- a/pkg/insecure/proxy.go +++ b/pkg/insecure/proxy.go @@ -140,17 +140,34 @@ func (p *TLSProxy) Close() error { return p.server.Shutdown(ctx) } -func newProxyHandler(hostname string) (*httputil.ReverseProxy, error) { +func parseURL(hostname string) (*url.URL, error) { + if strings.HasPrefix(hostname, "http://") { + return nil, errors.New("scheme must be https") + } + if !strings.HasPrefix(hostname, "http") { + hostname = "https://" + hostname + } target, err := url.Parse(hostname) + if err != nil { + return nil, errors.Wrap(err, "parse url") + } + if target.Scheme == "" { + target.Scheme = "https" + } + + return target, nil +} + +func newProxyHandler(hostname string) (*httputil.ReverseProxy, error) { + target, err := parseURL(hostname) if err != nil { return nil, errors.Wrap(err, "parse hostname") } - target.Scheme = "https" reverseProxy := &httputil.ReverseProxy{ Director: func(req *http.Request) { req.Host = target.Host - req.URL.Scheme = "https" + req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL) }, diff --git a/pkg/insecure/proxy_test.go b/pkg/insecure/proxy_test.go index c32f1fec4f..8833fef323 100644 --- a/pkg/insecure/proxy_test.go +++ b/pkg/insecure/proxy_test.go @@ -1,6 +1,7 @@ package insecure import ( + "net/url" "testing" "github.com/stretchr/testify/assert" @@ -8,7 +9,56 @@ import ( ) func TestProxy(t *testing.T) { + t.Parallel() + proxy, err := NewTLSProxy("localhost") require.NoError(t, err) assert.NotZero(t, proxy.Port) } + +func TestParseURL(t *testing.T) { + t.Parallel() + + testCases := []struct { + input string + shouldErr bool + expected *url.URL + }{ + { + input: "localhost:8080", + expected: &url.URL{Scheme: "https", Host: "localhost:8080"}, + }, + { + input: "https://localhost:8080", + expected: &url.URL{Scheme: "https", Host: "localhost:8080"}, + }, + { + input: "http://localhost:8080", + shouldErr: true, + }, + { + input: "https://fleetdm.com/prefix", + expected: &url.URL{Scheme: "https", Host: "fleetdm.com", Path: "/prefix"}, + }, + { + input: "fleetdm.com/prefix", + expected: &url.URL{Scheme: "https", Host: "fleetdm.com", Path: "/prefix"}, + }, + { + input: " **foobar", + shouldErr: true, + }, + } + + for _, tt := range testCases { + t.Run(tt.input, func(t *testing.T) { + url, err := parseURL(tt.input) + if tt.shouldErr { + require.Error(t, err) + return + } + + assert.Equal(t, tt.expected, url) + }) + } +} From d9f979d2775b665c70c91549a094179ae2fdfcc6 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 24 Feb 2021 16:36:55 -0800 Subject: [PATCH 052/115] Improve connection compatibility - Properly handle URL prefixes in Fleet server - Allow specifying certificate with `--fleet-certificate` - Add check for TLS connection on startup --- cmd/orbit/orbit.go | 92 +++++++++++++++++++++++------ pkg/certificate/certificate.go | 56 ++++++++++++++++++ pkg/certificate/certificate_test.go | 22 +++++++ pkg/certificate/testdata/empty.crt | 1 + pkg/insecure/proxy.go | 3 - pkg/osquery/flags.go | 22 ++++--- 6 files changed, 167 insertions(+), 29 deletions(-) create mode 100644 pkg/certificate/testdata/empty.crt diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 3c9e93cee0..c62ec79f59 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -2,13 +2,16 @@ package main import ( "context" + "crypto/x509" "fmt" "io/ioutil" + "net/url" "os" "path/filepath" "strings" "time" + "github.com/fleetdm/orbit/pkg/certificate" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" "github.com/fleetdm/orbit/pkg/insecure" @@ -57,6 +60,11 @@ func main() { Usage: "URL (host:port) of Fleet server", EnvVars: []string{"ORBIT_FLEET_URL"}, }, + &cli.StringFlag{ + Name: "fleet-certificate", + Usage: "Path to server cerificate bundle", + EnvVars: []string{"ORBIT_FLEET_CERTIFICATE"}, + }, &cli.StringFlag{ Name: "tuf-url", Usage: "URL of TUF update server", @@ -90,6 +98,10 @@ func main() { zerolog.SetGlobalLevel(zerolog.DebugLevel) } + if c.Bool("insecure") && c.String("fleet-certificate") != "" { + return errors.New("insecure and fleet-certificate may not be specified together") + } + if c.String("enroll-secret-path") != "" { if c.String("enroll-secret") != "" { return errors.New("enroll-secret and enroll-secret-path may not be specified together") @@ -159,8 +171,19 @@ func main() { options = append(options, osquery.WithDataPath(c.String("root-dir"))) fleetURL := c.String("fleet-url") + if !strings.HasPrefix(fleetURL, "http") { + fleetURL = "https://" + fleetURL + } - if c.Bool("insecure") { + enrollSecret := c.String("enroll-secret") + if enrollSecret != "" { + options = append(options, + osquery.WithEnv([]string{"ENROLL_SECRET=" + enrollSecret}), + osquery.WithFlags([]string{"--enroll_secret_env=ENROLL_SECRET"}), + ) + } + + if fleetURL != "" && c.Bool("insecure") { proxy, err := insecure.NewTLSProxy(fleetURL) if err != nil { return errors.Wrap(err, "create TLS proxy") @@ -188,33 +211,66 @@ func main() { return errors.Wrap(err, "write server cert") } - // Rewrite URL to the proxy URL - fleetURL = fmt.Sprintf("localhost:%d", proxy.Port) + // Rewrite URL to the proxy URL. Note the proxy handles any URL + // prefix so we don't need to carry that over here. + parsedURL := &url.URL{ + Scheme: "https", + Host: fmt.Sprintf("localhost:%d", proxy.Port), + } + + // Check and log if there are any errors with TLS connection. + pool, err := certificate.LoadPEM(certPath) + if err != nil { + return errors.Wrap(err, "load certificate") + } + if err := certificate.ValidateConnection(pool, fleetURL); err != nil { + log.Info().Err(err).Msg("Failed to connect to Fleet server. Osquery connection may fail.") + } options = append(options, - osquery.WithFlags(osquery.FleetFlags(fleetURL)), + osquery.WithFlags(osquery.FleetFlags(parsedURL)), osquery.WithFlags([]string{"--tls_server_certs", certPath}), ) - } - - enrollSecret := c.String("enroll-secret") - if enrollSecret != "" { - options = append(options, - osquery.WithEnv([]string{"ENROLL_SECRET=" + enrollSecret}), - osquery.WithFlags([]string{"--enroll_secret_env", "ENROLL_SECRET"}), - ) - } - - if fleetURL != "" { + } else if fleetURL != "" { if enrollSecret == "" { return errors.New("enroll secret must be specified to connect to Fleet server") } + parsedURL, err := url.Parse(fleetURL) + if err != nil { + return errors.Wrap(err, "parse URL") + } + options = append(options, - osquery.WithFlags(osquery.FleetFlags(fleetURL)), + osquery.WithFlags(osquery.FleetFlags(parsedURL)), ) + + if certPath := c.String("fleet-certificate"); certPath != "" { + // Check and log if there are any errors with TLS connection. + pool, err := certificate.LoadPEM(certPath) + if err != nil { + return errors.Wrap(err, "load certificate") + } + if err := certificate.ValidateConnection(pool, fleetURL); err != nil { + log.Info().Err(err).Msg("Failed to connect to Fleet server. Osquery connection may fail.") + } + + options = append(options, + osquery.WithFlags([]string{"--tls_server_certs=" + certPath}), + ) + } else { + // Check and log if there are any errors with TLS connection. + pool, err := x509.SystemCertPool() + if err != nil { + log.Info().Err(err).Msg("Failed to retrieve system cert pool. Cannot validate Fleet server connection.") + } else if err := certificate.ValidateConnection(pool, fleetURL); err != nil { + log.Info().Err(err).Msg("Failed to connect to Fleet server. Osquery connection may fail. Provide certificate with --fleet-certificate.") + } + } } + // --force is sometimes needed when an older osquery process has not + // exited properly options = append(options, osquery.WithFlags([]string{"--force"})) if c.Bool("debug") { @@ -224,7 +280,7 @@ func main() { } // Handle additional args after -- - options = append(options, osquery.WithFlags([]string(c.Args().Slice()))) + options = append(options, osquery.WithFlags(c.Args().Slice())) // Create an osquery runner with the provided options r, _ := osquery.NewRunner(osquerydPath, options...) @@ -313,7 +369,7 @@ var shellCommand = &cli.Command{ osquerydPath, osquery.WithShell(), // Handle additional args after -- - osquery.WithFlags([]string(c.Args().Slice())), + osquery.WithFlags(c.Args().Slice()), osquery.WithDataPath(c.String("root-dir")), ) g.Add(r.Execute, r.Interrupt) diff --git a/pkg/certificate/certificate.go b/pkg/certificate/certificate.go index 9b7a4a139c..2f9d29e88f 100644 --- a/pkg/certificate/certificate.go +++ b/pkg/certificate/certificate.go @@ -4,7 +4,10 @@ package certificate import ( "bytes" "crypto/tls" + "crypto/x509" "encoding/pem" + "io/ioutil" + "net/url" "github.com/pkg/errors" ) @@ -34,3 +37,56 @@ func FetchPEM(hostname string) ([]byte, error) { } return b.Bytes(), nil } + +// LoadPEM loads certificates from a PEM file and returns a cert pool containing +// the certificates. +func LoadPEM(path string) (*x509.CertPool, error) { + pool := x509.NewCertPool() + + contents, err := ioutil.ReadFile(path) + if err != nil { + return nil, errors.Wrap(err, "read certificate file") + } + + if ok := pool.AppendCertsFromPEM(contents); !ok { + return nil, errors.Errorf("no valid ceritificates found in %s", path) + } + + return pool, nil +} + +// ValidateConnection checks that a connection can be successfully established +// to the server URL using the cert pool provided. The validation performed is +// not sufficient to verify authenticity of the server, but it can help to catch +// certificate errors and provide more detailed messages to users. +func ValidateConnection(pool *x509.CertPool, fleetURL string) error { + parsed, err := url.Parse(fleetURL) + if err != nil { + return errors.Wrap(err, "parse url") + } + conn, err := tls.Dial("tcp", parsed.Host, &tls.Config{ + ClientCAs: pool, + InsecureSkipVerify: true, + VerifyConnection: func(state tls.ConnectionState) error { + if len(state.PeerCertificates) == 0 { + return errors.New("no peer certificates") + } + + cert := state.PeerCertificates[0] + if _, err := cert.Verify(x509.VerifyOptions{ + DNSName: parsed.Hostname(), + Roots: pool, + }); err != nil { + return errors.Wrap(err, "verify certificate") + } + + return nil + }, + }) + if err != nil { + return errors.Wrap(err, "dial for validate") + } + defer conn.Close() + + return nil +} diff --git a/pkg/certificate/certificate_test.go b/pkg/certificate/certificate_test.go index 13104a4e31..80c1b8418b 100644 --- a/pkg/certificate/certificate_test.go +++ b/pkg/certificate/certificate_test.go @@ -46,3 +46,25 @@ func TestFetchPEM(t *testing.T) { require.NoError(t, err) assert.Equal(t, expectedCert, pem) } + +func TestLoadPEM(t *testing.T) { + t.Parallel() + + pool, err := LoadPEM(filepath.Join("testdata", "test.crt")) + require.NoError(t, err) + assert.True(t, len(pool.Subjects()) > 0) +} + +func TestLoadErrorNoCertificates(t *testing.T) { + t.Parallel() + + _, err := LoadPEM(filepath.Join("testdata", "empty.crt")) + require.Error(t, err) +} + +func TestLoadErrorMissingFile(t *testing.T) { + t.Parallel() + + _, err := LoadPEM(filepath.Join("testdata", "invalid_path")) + require.Error(t, err) +} diff --git a/pkg/certificate/testdata/empty.crt b/pkg/certificate/testdata/empty.crt new file mode 100644 index 0000000000..8e0ca234a9 --- /dev/null +++ b/pkg/certificate/testdata/empty.crt @@ -0,0 +1 @@ +no cert contained in here diff --git a/pkg/insecure/proxy.go b/pkg/insecure/proxy.go index 804e2df49d..ca4add24c6 100644 --- a/pkg/insecure/proxy.go +++ b/pkg/insecure/proxy.go @@ -144,9 +144,6 @@ func parseURL(hostname string) (*url.URL, error) { if strings.HasPrefix(hostname, "http://") { return nil, errors.New("scheme must be https") } - if !strings.HasPrefix(hostname, "http") { - hostname = "https://" + hostname - } target, err := url.Parse(hostname) if err != nil { return nil, errors.Wrap(err, "parse url") diff --git a/pkg/osquery/flags.go b/pkg/osquery/flags.go index 065286baae..ca7376660e 100644 --- a/pkg/osquery/flags.go +++ b/pkg/osquery/flags.go @@ -1,22 +1,28 @@ package osquery +import ( + "net/url" + "path" +) + // FleetFlags is the set of flags to pass to osquery when connecting to Fleet. -func FleetFlags(hostname string) []string { +func FleetFlags(fleetURL *url.URL) []string { + hostname, prefix := fleetURL.Host, fleetURL.Path return []string{ "--tls_hostname=" + hostname, - "--enroll_tls_endpoint=/api/v1/osquery/enroll", + "--enroll_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/enroll"), "--config_plugin=tls", - "--config_tls_endpoint=/api/v1/osquery/config", + "--config_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/config"), "--disable_distributed=false", "--distributed_plugin=tls", "--distributed_tls_max_attempts=10", - "--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read", - "--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write", + "--distributed_tls_read_endpoint=" + path.Join(prefix, "/api/v1/osquery/distributed/read"), + "--distributed_tls_write_endpoint=" + path.Join(prefix, "/api/v1/osquery/distributed/write"), "--logger_plugin=tls", - "--logger_tls_endpoint=/api/v1/osquery/log", + "--logger_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/log"), "--disable_carver=false", - "--carver_start_endpoint=/api/v1/osquery/carve/begin", - "--carver_continue_endpoint=/api/v1/osquery/carve/block", + "--carver_start_endpoint=" + path.Join(prefix, "/api/v1/osquery/carve/begin"), + "--carver_continue_endpoint=" + path.Join(prefix, "/api/v1/osquery/carve/block"), "--carver_block_size=2000000", } } From bb6a78530916f38175f38e535689d234cf0e92f4 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 24 Feb 2021 16:49:26 -0800 Subject: [PATCH 053/115] Clean up URL parsing in proxy --- pkg/insecure/proxy.go | 25 ++++---------------- pkg/insecure/proxy_test.go | 48 -------------------------------------- 2 files changed, 5 insertions(+), 68 deletions(-) diff --git a/pkg/insecure/proxy.go b/pkg/insecure/proxy.go index ca4add24c6..520625f336 100644 --- a/pkg/insecure/proxy.go +++ b/pkg/insecure/proxy.go @@ -85,7 +85,7 @@ type TLSProxy struct { // NewTLSProxy creates a new proxy implementation targeting the provided // hostname. -func NewTLSProxy(targetHostname string) (*TLSProxy, error) { +func NewTLSProxy(targetURL string) (*TLSProxy, error) { cert, err := tls.X509KeyPair([]byte(ServerCert), []byte(serverKey)) if err != nil { return nil, errors.Wrap(err, "load keypair") @@ -103,7 +103,7 @@ func NewTLSProxy(targetHostname string) (*TLSProxy, error) { return nil, errors.New("listener is not *net.TCPAddr") } - handler, err := newProxyHandler(targetHostname) + handler, err := newProxyHandler(targetURL) if err != nil { return nil, errors.Wrap(err, "make proxy handler") } @@ -140,25 +140,10 @@ func (p *TLSProxy) Close() error { return p.server.Shutdown(ctx) } -func parseURL(hostname string) (*url.URL, error) { - if strings.HasPrefix(hostname, "http://") { - return nil, errors.New("scheme must be https") - } - target, err := url.Parse(hostname) +func newProxyHandler(targetURL string) (*httputil.ReverseProxy, error) { + target, err := url.Parse(targetURL) if err != nil { - return nil, errors.Wrap(err, "parse url") - } - if target.Scheme == "" { - target.Scheme = "https" - } - - return target, nil -} - -func newProxyHandler(hostname string) (*httputil.ReverseProxy, error) { - target, err := parseURL(hostname) - if err != nil { - return nil, errors.Wrap(err, "parse hostname") + return nil, errors.Wrap(err, "parse target url") } reverseProxy := &httputil.ReverseProxy{ diff --git a/pkg/insecure/proxy_test.go b/pkg/insecure/proxy_test.go index 8833fef323..5c0be4e893 100644 --- a/pkg/insecure/proxy_test.go +++ b/pkg/insecure/proxy_test.go @@ -1,7 +1,6 @@ package insecure import ( - "net/url" "testing" "github.com/stretchr/testify/assert" @@ -15,50 +14,3 @@ func TestProxy(t *testing.T) { require.NoError(t, err) assert.NotZero(t, proxy.Port) } - -func TestParseURL(t *testing.T) { - t.Parallel() - - testCases := []struct { - input string - shouldErr bool - expected *url.URL - }{ - { - input: "localhost:8080", - expected: &url.URL{Scheme: "https", Host: "localhost:8080"}, - }, - { - input: "https://localhost:8080", - expected: &url.URL{Scheme: "https", Host: "localhost:8080"}, - }, - { - input: "http://localhost:8080", - shouldErr: true, - }, - { - input: "https://fleetdm.com/prefix", - expected: &url.URL{Scheme: "https", Host: "fleetdm.com", Path: "/prefix"}, - }, - { - input: "fleetdm.com/prefix", - expected: &url.URL{Scheme: "https", Host: "fleetdm.com", Path: "/prefix"}, - }, - { - input: " **foobar", - shouldErr: true, - }, - } - - for _, tt := range testCases { - t.Run(tt.input, func(t *testing.T) { - url, err := parseURL(tt.input) - if tt.shouldErr { - require.Error(t, err) - return - } - - assert.Equal(t, tt.expected, url) - }) - } -} From a22eb168454935b514abbd9e966b12544e7fb394 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 25 Feb 2021 12:38:21 -0800 Subject: [PATCH 054/115] Add support for packaging certificates - Refactor update initialization --- cmd/package/package.go | 5 ++++ pkg/packaging/deb.go | 29 +++++++--------------- pkg/packaging/macos.go | 42 +++++++++++++++++--------------- pkg/packaging/macos_templates.go | 1 + pkg/packaging/packaging.go | 34 ++++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 39 deletions(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index 0ba6ef05bb..fa2c7af43a 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -38,6 +38,11 @@ func main() { Usage: "URL (host:port) of Fleet server", Destination: &opt.FleetURL, }, + &cli.StringFlag{ + Name: "fleet-certificate", + Usage: "Path to server cerificate bundle", + Destination: &opt.FleetCertificate, + }, &cli.StringFlag{ Name: "identifier", Usage: "Identifier for package product", diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 0476348922..98825b9260 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -9,7 +9,6 @@ import ( "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/goreleaser/nfpm/v2" "github.com/goreleaser/nfpm/v2/deb" "github.com/goreleaser/nfpm/v2/files" @@ -38,28 +37,17 @@ func BuildDeb(opt Options) error { // Initialize autoupdate metadata - localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) - if err != nil { - return errors.Wrap(err, "failed to create local metadata store") - } updateOpt := update.DefaultOptions - updateOpt.RootDirectory = orbitRoot - updateOpt.ServerURL = "https://tuf.fleetctl.com" - updateOpt.LocalStore = localStore updateOpt.Platform = "linux" + updateOpt.RootDirectory = orbitRoot - updater, err := update.New(updateOpt) - if err != nil { - return errors.Wrap(err, "failed to init updater") + // TODO these should be configurable + updateOpt.ServerURL = "https://tuf.fleetctl.com" + osqueryChannel, orbitChannel := "stable", "stable" + + if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + return errors.Wrap(err, "initialize updates") } - if err := updater.UpdateMetadata(); err != nil { - return errors.Wrap(err, "failed to update metadata") - } - osquerydPath, err := updater.Get("osqueryd", "stable") - if err != nil { - return errors.Wrap(err, "failed to get osqueryd") - } - log.Debug().Str("path", osquerydPath).Msg("got osqueryd") // Write files @@ -161,7 +149,7 @@ After=network.service syslog.service [Service] TimeoutStartSec=0 EnvironmentFile=/etc/default/orbit -ExecStart=/usr/local/bin/orbit +ExecStart=/var/lib/orbit/orbit Restart=on-failure KillMode=control-group KillSignal=SIGTERM @@ -181,6 +169,7 @@ WantedBy=multi-user.target var envTemplate = template.Must(template.New("env").Parse(` {{- if .Insecure }}ORBIT_INSECURE=true{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} +{{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} `)) diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 304af9cd2d..26ffb6f215 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -11,7 +11,6 @@ import ( "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" - "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" "github.com/rs/zerolog/log" ) @@ -41,28 +40,17 @@ func BuildPkg(opt Options) error { // Initialize autoupdate metadata - localStore, err := filestore.New(filepath.Join(orbitRoot, "tuf-metadata.json")) - if err != nil { - return errors.Wrap(err, "failed to create local metadata store") - } updateOpt := update.DefaultOptions - updateOpt.RootDirectory = orbitRoot - updateOpt.ServerURL = "https://tuf.fleetctl.com" - updateOpt.LocalStore = localStore updateOpt.Platform = "macos" + updateOpt.RootDirectory = orbitRoot - updater, err := update.New(updateOpt) - if err != nil { - return errors.Wrap(err, "failed to init updater") + // TODO these should be configurable + updateOpt.ServerURL = "https://tuf.fleetctl.com" + osqueryChannel, orbitChannel := "stable", "stable" + + if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + return errors.Wrap(err, "initialize updates") } - if err := updater.UpdateMetadata(); err != nil { - return errors.Wrap(err, "failed to update metadata") - } - osquerydPath, err := updater.Get("osqueryd", "stable") - if err != nil { - return errors.Wrap(err, "failed to get osqueryd") - } - log.Debug().Str("path", osquerydPath).Msg("got osqueryd") // Write files @@ -83,6 +71,11 @@ func BuildPkg(opt Options) error { return errors.Wrap(err, "write launchd") } } + if opt.FleetCertificate != "" { + if err := writeCertificate(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write fleet certificate") + } + } if err := copyFile( "./orbit", filepath.Join(orbitRoot, "bin", "orbit", "macos", "current", "orbit"), @@ -210,6 +203,17 @@ func writeDistribution(opt Options, rootPath string) error { return nil } +func writeCertificate(opt Options, orbitRoot string) error { + // Fleet TLS certificate + dstPath := filepath.Join(orbitRoot, "fleet.pem") + + if err := copyFile(opt.FleetCertificate, dstPath, 0644); err != nil { + return errors.Wrap(err, "write orbit") + } + + return nil +} + // xarBom creates the actual .pkg format. It's a xar archive with a BOM (Bill of // materials?). See http://bomutils.dyndns.org/tutorial.html. func xarBom(opt Options, rootPath string) error { diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index ebf451a850..8ecdea473c 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -70,6 +70,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} + {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} KeepAlive diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 2994a4db9f..7d75bf643d 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -6,7 +6,10 @@ import ( "os" "path/filepath" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Options are the configurable options provided for the package. @@ -29,6 +32,8 @@ type Options struct { SignIdentity string // Notarize sets whether macOS packages should be Notarized. Notarize bool + // FleetCertificate is a path to a server certificate to include in the package. + FleetCertificate string } func copyFile(srcPath, dstPath string, perm os.FileMode) error { @@ -54,3 +59,32 @@ func copyFile(srcPath, dstPath string, perm os.FileMode) error { return nil } + +func initializeUpdates(updateOpt update.Options, osqueryChannel, orbitChannel string) error { + localStore, err := filestore.New(filepath.Join(updateOpt.RootDirectory, "tuf-metadata.json")) + if err != nil { + return errors.Wrap(err, "failed to create local metadata store") + } + updateOpt.LocalStore = localStore + + updater, err := update.New(updateOpt) + if err != nil { + return errors.Wrap(err, "failed to init updater") + } + if err := updater.UpdateMetadata(); err != nil { + return errors.Wrap(err, "failed to update metadata") + } + osquerydPath, err := updater.Get("osqueryd", osqueryChannel) + if err != nil { + return errors.Wrap(err, "failed to get osqueryd") + } + log.Debug().Str("path", osquerydPath).Msg("got osqueryd") + + orbitPath, err := updater.Get("orbit", orbitChannel) + if err != nil { + return errors.Wrap(err, "failed to get orbit") + } + log.Debug().Str("path", orbitPath).Msg("got orbit") + + return nil +} From 4bc6b8afeb001364eeae10d40e0ea275b5966866 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 1 Mar 2021 11:16:19 -0800 Subject: [PATCH 055/115] Ensure Fleet URL is prefixed with https --- cmd/orbit/orbit.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index c62ec79f59..ab9e9ebb51 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -183,7 +183,7 @@ func main() { ) } - if fleetURL != "" && c.Bool("insecure") { + if fleetURL != "https://" && c.Bool("insecure") { proxy, err := insecure.NewTLSProxy(fleetURL) if err != nil { return errors.Wrap(err, "create TLS proxy") @@ -231,7 +231,7 @@ func main() { osquery.WithFlags(osquery.FleetFlags(parsedURL)), osquery.WithFlags([]string{"--tls_server_certs", certPath}), ) - } else if fleetURL != "" { + } else if fleetURL != "https://" { if enrollSecret == "" { return errors.New("enroll secret must be specified to connect to Fleet server") } From 7e4d661e84f62a7bc5072d0c35e4372dae44e12e Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 1 Mar 2021 11:16:38 -0800 Subject: [PATCH 056/115] Move osqueryd run message to info log --- pkg/osquery/osquery.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index e8a8af5847..01eaa33066 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -103,7 +103,7 @@ func WithLogPath(path string) func(*Runner) error { // process may not be restarted after exit. Instead create a new one with // NewRunner. func (r *Runner) Execute() error { - log.Debug().Str("cmd", r.cmd.String()).Msg("run osqueryd") + log.Info().Str("cmd", r.cmd.String()).Msg("run osqueryd") ctx, cancel := context.WithCancel(context.Background()) r.cancel = cancel From 643201a8ef99cf91e030fcea0b7b9d885546eab0 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 11:24:02 -0800 Subject: [PATCH 057/115] Add logs directory to macos cleanup script --- tools/cleanup/cleanup_macos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/cleanup/cleanup_macos.sh b/tools/cleanup/cleanup_macos.sh index 8e735a17b2..a410b054a3 100755 --- a/tools/cleanup/cleanup_macos.sh +++ b/tools/cleanup/cleanup_macos.sh @@ -3,4 +3,4 @@ sudo launchctl stop com.fleetdm.orbit sudo launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist -sudo rm -rf /Library/LaunchDaemons/com.fleetdm.orbit.plist /var/lib/orbit/ /usr/local/bin/orbit +sudo rm -rf /Library/LaunchDaemons/com.fleetdm.orbit.plist /var/lib/orbit/ /usr/local/bin/orbit /var/log/orbit From bc39118883b321e76df57357706466266f2cf5bc Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 11:24:32 -0800 Subject: [PATCH 058/115] Use symlink for current orbit binary --- cmd/package/package.go | 4 ++++ pkg/packaging/deb.go | 5 +++-- pkg/packaging/macos.go | 21 ++++++++++++--------- pkg/packaging/macos_templates.go | 5 +++-- pkg/packaging/packaging.go | 10 +++++++--- pkg/update/update.go | 6 ++++++ 6 files changed, 35 insertions(+), 16 deletions(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index fa2c7af43a..8d1308aade 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -94,6 +94,10 @@ func main() { } } + // TODO take these from flags + opt.OrbitChannel = "stable" + opt.OsqueryChannel = "stable" + switch c.String("type") { case "pkg": return packaging.BuildPkg(opt) diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 98825b9260..9b7692282b 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -40,12 +40,13 @@ func BuildDeb(opt Options) error { updateOpt := update.DefaultOptions updateOpt.Platform = "linux" updateOpt.RootDirectory = orbitRoot + updateOpt.OrbitChannel = opt.OrbitChannel + updateOpt.OsqueryChannel = opt.OsqueryChannel // TODO these should be configurable updateOpt.ServerURL = "https://tuf.fleetctl.com" - osqueryChannel, orbitChannel := "stable", "stable" - if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") } diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 26ffb6f215..bc4a4c9dae 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -43,12 +43,13 @@ func BuildPkg(opt Options) error { updateOpt := update.DefaultOptions updateOpt.Platform = "macos" updateOpt.RootDirectory = orbitRoot + updateOpt.OrbitChannel = opt.OrbitChannel + updateOpt.OsqueryChannel = opt.OsqueryChannel // TODO these should be configurable updateOpt.ServerURL = "https://tuf.fleetctl.com" - osqueryChannel, orbitChannel := "stable", "stable" - if err := initializeUpdates(updateOpt, osqueryChannel, orbitChannel); err != nil { + if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") } @@ -76,13 +77,15 @@ func BuildPkg(opt Options) error { return errors.Wrap(err, "write fleet certificate") } } - if err := copyFile( - "./orbit", - filepath.Join(orbitRoot, "bin", "orbit", "macos", "current", "orbit"), - 0755, - ); err != nil { - return errors.Wrap(err, "write orbit") - } + + // TODO gate behind a flag and allow copying a local orbit + // if err := copyFile( + // "./orbit", + // filepath.Join(orbitRoot, "bin", "orbit", "macos", "current", "orbit"), + // 0755, + // ); err != nil { + // return errors.Wrap(err, "write orbit") + // } // Build package if err := xarBom(opt, tmpDir); err != nil { diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 8ecdea473c..361eeabf1a 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -33,7 +33,8 @@ var macosDistributionTemplate = template.Must(template.New("").Option("missingke var macosPostinstallTemplate = template.Must(template.New("").Option("missingkey=error").Parse( `#!/bin/bash -ln -sf /var/lib/orbit/orbit /usr/local/bin/orbit +ln -sf /var/lib/orbit/bin/orbit/macos/{{.OrbitChannel}}/orbit /var/lib/orbit/bin/orbit/orbit +ln -sf /var/lib/orbit/bin/orbit/orbit /usr/local/bin/orbit {{ if .StartService -}} launchctl stop com.fleetdm.orbit @@ -60,7 +61,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err com.fleetdm.orbit ProgramArguments - /var/lib/orbit/bin/orbit/macos/current/orbit + /var/lib/orbit/bin/orbit/orbit StandardOutPath /var/log/orbit/orbit.stdout.log diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 7d75bf643d..3b59a03dca 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -34,6 +34,10 @@ type Options struct { Notarize bool // FleetCertificate is a path to a server certificate to include in the package. FleetCertificate string + // OrbitChannel is the update channel to use for Orbit. + OrbitChannel string + // OsqueryChannel is the update channel to use for Osquery. + OsqueryChannel string } func copyFile(srcPath, dstPath string, perm os.FileMode) error { @@ -60,7 +64,7 @@ func copyFile(srcPath, dstPath string, perm os.FileMode) error { return nil } -func initializeUpdates(updateOpt update.Options, osqueryChannel, orbitChannel string) error { +func initializeUpdates(updateOpt update.Options) error { localStore, err := filestore.New(filepath.Join(updateOpt.RootDirectory, "tuf-metadata.json")) if err != nil { return errors.Wrap(err, "failed to create local metadata store") @@ -74,13 +78,13 @@ func initializeUpdates(updateOpt update.Options, osqueryChannel, orbitChannel st if err := updater.UpdateMetadata(); err != nil { return errors.Wrap(err, "failed to update metadata") } - osquerydPath, err := updater.Get("osqueryd", osqueryChannel) + osquerydPath, err := updater.Get("osqueryd", updateOpt.OsqueryChannel) if err != nil { return errors.Wrap(err, "failed to get osqueryd") } log.Debug().Str("path", osquerydPath).Msg("got osqueryd") - orbitPath, err := updater.Get("orbit", orbitChannel) + orbitPath, err := updater.Get("orbit", updateOpt.OrbitChannel) if err != nil { return errors.Wrap(err, "failed to get orbit") } diff --git a/pkg/update/update.go b/pkg/update/update.go index 2fd31de1e2..9ee33d5716 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -46,6 +46,10 @@ type Options struct { // Platform is the target of the platform to update for. In the default // options this is the current platform. Platform string + // OrbitChannel is the update channel to use for Orbit. + OrbitChannel string + // OsqueryChannel is the update channel to use for Osquery. + OsqueryChannel string } var ( @@ -58,6 +62,8 @@ var ( InsecureTransport: false, Platform: constant.PlatformName, RootKeys: defaultRootKeys, + OrbitChannel: "stable", + OsqueryChannel: "stable", } ) From 85b0853ebd917419d9584b02e18b64f3c05bffcf Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 11:24:57 -0800 Subject: [PATCH 059/115] Remove config_path from osquery flags This was not used previously due to conflicting flags --- pkg/osquery/osquery.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/osquery/osquery.go b/pkg/osquery/osquery.go index 01eaa33066..edba97ced4 100644 --- a/pkg/osquery/osquery.go +++ b/pkg/osquery/osquery.go @@ -79,7 +79,6 @@ func WithDataPath(path string) func(*Runner) error { "--pidfile="+filepath.Join(path, "osquery.pid"), "--database_path="+filepath.Join(path, "osquery.db"), "--extensions_socket="+filepath.Join(path, "osquery.em"), - "--config_path="+filepath.Join(path, "osquery.conf"), ) return nil } From b8c95154ac172ec8edd3614acd8998940ba3e053 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 11:25:26 -0800 Subject: [PATCH 060/115] Simplify shell command startup --- cmd/orbit/orbit.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index ab9e9ebb51..6908f72fa3 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -329,16 +329,6 @@ var shellCommand = &cli.Command{ return errors.Wrap(err, "initialize root dir") } - db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) - if err != nil { - return err - } - defer func() { - if err := db.Close(); err != nil { - log.Error().Err(err).Msg("close badger") - } - }() - localStore, err := filestore.New(filepath.Join(c.String("root-dir"), "tuf-metadata.json")) if err != nil { log.Fatal().Err(err).Msg("failed to create local metadata store") @@ -370,7 +360,6 @@ var shellCommand = &cli.Command{ osquery.WithShell(), // Handle additional args after -- osquery.WithFlags(c.Args().Slice()), - osquery.WithDataPath(c.String("root-dir")), ) g.Add(r.Execute, r.Interrupt) From 73be4c0fe94b0267e30a208b3e19ec17ecfe5833 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 11:26:20 -0800 Subject: [PATCH 061/115] Update README with usage information --- README.md | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0dee28764a..04f98489cc 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,57 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autou ## Usage -TODO +General information and flag documentation can be accessed by running `orbit --help`. + +### Permissions + +Orbit generally expects root permissions to be able to create and access it's working files. + +To get root level permissions: + +#### macOS/Linux + +Prefix `orbit` commands with `sudo` (`sudo orbit ...`) or run in a root shell. + +#### Windows + +Run Powershell or cmd.exe with "Run as administrator" and start `orbit` commands from that shell. + +### Osquery shell + +Run an `osqueryi` shell with `orbit osqueryi` or `orbit shell`. + +### Connect to a Fleet server + +Use the `--fleet-url` and `--enroll-secret` flags to connect to a Fleet server. + +For example: + +``` sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value +``` + +Use `--fleet_certificate` to provide a path to a certificate bundle when necessary for osquery to verify the authenticity of the Fleet server (typically when using a Windows client or self-signed certificates): + +``` sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --fleet-certificate=cert.pem +``` + +Add the `--insecure` flag for connections using otherwise invalid certificates: + +``` sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --insecure +``` + +### Osquery flags + +Orbit can be used as near drop-in replacement for `osqueryd`, enhancing standard osquery with autoupdate capabilities. Orbit passes through any options after `--` directly to the `osqueryd` instance. + +For example, the following would be a typical drop-in usage of Orbit: + +``` sh +orbit -- --flagfile=flags.txt +``` ## Packaging From b154b596c09e7ec6f5a27bfac65b36179efadcbc Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 12:05:56 -0800 Subject: [PATCH 062/115] Prevent insecure and fleet-certificate from being packaged together These were already not allowed on Orbit startup. --- cmd/package/package.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/package/package.go b/cmd/package/package.go index 8d1308aade..04994d1e52 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -94,6 +94,10 @@ func main() { } } + if opt.Insecure && opt.FleetCertificate != "" { + return errors.New("--insecure and --fleet-certificate may not be provided together") + } + // TODO take these from flags opt.OrbitChannel = "stable" opt.OsqueryChannel = "stable" From 34d48bac35592a33e9f60cc03d6c52d849953406 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 13:07:26 -0800 Subject: [PATCH 063/115] Add Orbit itself to update runner Now Orbit will attempt to autoupdate Orbit. --- cmd/orbit/orbit.go | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 6908f72fa3..75c1f9ae2f 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -82,10 +82,16 @@ func main() { EnvVars: []string{"ORBIT_ENROLL_SECRET_PATH"}, }, &cli.StringFlag{ - Name: "osquery-version", - Usage: "Version of osquery to use", + Name: "osquery-channel", + Usage: "Update channel of osquery to use", Value: "stable", - EnvVars: []string{"ORBIT_OSQUERY_VERSION"}, + EnvVars: []string{"ORBIT_OSQUERY_CHANNEL"}, + }, + &cli.StringFlag{ + Name: "orbit-channel", + Usage: "Update channel of orbit to use", + Value: "stable", + EnvVars: []string{"ORBI_ORBIT_CHANNEL"}, }, &cli.BoolFlag{ Name: "debug", @@ -149,7 +155,7 @@ func main() { if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osquery-version")) + osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) if err != nil { return err } @@ -159,7 +165,8 @@ func main() { updateRunner, err := update.NewRunner(updater, update.RunnerOptions{ CheckInterval: 10 * time.Second, Targets: map[string]string{ - "osqueryd": c.String("osquery-version"), + "osqueryd": c.String("osquery-channel"), + "orbit": c.String("orbit-channel"), }, }) if err != nil { @@ -309,10 +316,10 @@ var shellCommand = &cli.Command{ Usage: "Run the osqueryi shell", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "osquery-version", - Usage: "Version of osquery to use", + Name: "osquery-channel", + Usage: "Channel of osquery version to use", Value: "stable", - EnvVars: []string{"ORBIT_OSQUERY_VERSION"}, + EnvVars: []string{"ORBIT_OSQUERY_CHANNEL"}, }, &cli.BoolFlag{ Name: "debug", @@ -347,7 +354,7 @@ var shellCommand = &cli.Command{ if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osquery-version")) + osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) if err != nil { return err } From b1b3f97ada959dd3e0dd5d3d73accff3539a9421 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 13:07:53 -0800 Subject: [PATCH 064/115] Fix DEB packaging - Handle restarts properly - Change symlinking --- pkg/packaging/deb.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 9b7692282b..8ff2847728 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -79,13 +79,21 @@ func BuildDeb(opt Options) error { Mode: constant.DefaultExecutableMode, }, }, + // Symlink current into /var/lib/orbit/bin/orbit/orbit &files.Content{ - Source: "/var/lib/orbit/orbit", + Source: "/var/lib/orbit/bin/orbit/linux/" + opt.OrbitChannel + "/orbit", + Destination: "/var/lib/orbit/bin/orbit/orbit", + Type: "symlink", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode | os.ModeSymlink, + }, + }, + // Symlink current into /usr/local/bin + &files.Content{ + Source: "/var/lib/orbit/bin/orbit/orbit", Destination: "/usr/local/bin/orbit", Type: "symlink", FileInfo: &files.ContentFileInfo{ - // TODO follow up on nfpm not respecting this - // https://github.com/goreleaser/nfpm/issues/286 Mode: constant.DefaultExecutableMode | os.ModeSymlink, }, }, @@ -146,12 +154,14 @@ func writeSystemdUnit(opt Options, rootPath string) error { [Unit] Description=Fleet Orbit osquery After=network.service syslog.service +StartLimitIntervalSec=0 [Service] TimeoutStartSec=0 EnvironmentFile=/etc/default/orbit -ExecStart=/var/lib/orbit/orbit -Restart=on-failure +ExecStart=/var/lib/orbit/bin/orbit/orbit +Restart=always +RestartSec=1 KillMode=control-group KillSignal=SIGTERM CPUQuota=20% @@ -206,7 +216,7 @@ set -e if [ -x /bin/systemctl ] && pidof systemd ; then /bin/systemctl daemon-reload 2>/dev/null 2>&1 {{ if .StartService -}} - /bin/systemctl start orbit.service 2>&1 + /bin/systemctl restart orbit.service 2>&1 {{- end}} fi `)) From fc6e6afd344db7c1fa7858c10e5a9edcf3ee2f7c Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 2 Mar 2021 17:19:24 -0800 Subject: [PATCH 065/115] Add support for RPM packages This was thankfully made easy by NFPM! Refactored the DEB packaging so that the code is almost entirely shared between the two. --- cmd/package/package.go | 4 +- go.sum | 5 + pkg/packaging/deb.go | 232 +-------------------------------- pkg/packaging/linux_shared.go | 233 ++++++++++++++++++++++++++++++++++ pkg/packaging/rpm.go | 7 + 5 files changed, 250 insertions(+), 231 deletions(-) create mode 100644 pkg/packaging/linux_shared.go create mode 100644 pkg/packaging/rpm.go diff --git a/cmd/package/package.go b/cmd/package/package.go index 04994d1e52..0e06c6795e 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -107,8 +107,10 @@ func main() { return packaging.BuildPkg(opt) case "deb": return packaging.BuildDeb(opt) + case "rpm": + return packaging.BuildRPM(opt) default: - return errors.New("type must be one of ('pkg', 'deb')") + return errors.New("type must be one of ('pkg', 'deb', 'rpm')") } } diff --git a/go.sum b/go.sum index 2d29b71e48..47e4368da6 100644 --- a/go.sum +++ b/go.sum @@ -67,6 +67,7 @@ github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -229,6 +230,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= +github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688 h1:jyGRCFMyDK/gKe6QRZQWci5+wEUBFElvxLHs3iwO3hY= github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= @@ -412,6 +414,7 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -465,6 +468,7 @@ github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6 github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= @@ -558,6 +562,7 @@ github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65 h1:Y0bLA422k github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= diff --git a/pkg/packaging/deb.go b/pkg/packaging/deb.go index 8ff2847728..b8ba100c1a 100644 --- a/pkg/packaging/deb.go +++ b/pkg/packaging/deb.go @@ -1,235 +1,7 @@ package packaging -import ( - "bytes" - "io/ioutil" - "os" - "path/filepath" - "text/template" - - "github.com/fleetdm/orbit/pkg/constant" - "github.com/fleetdm/orbit/pkg/update" - "github.com/goreleaser/nfpm/v2" - "github.com/goreleaser/nfpm/v2/deb" - "github.com/goreleaser/nfpm/v2/files" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" -) +import "github.com/goreleaser/nfpm/v2/deb" func BuildDeb(opt Options) error { - // Initialize directories - - tmpDir, err := ioutil.TempDir("", "orbit-package") - if err != nil { - return errors.Wrap(err, "failed to create temp dir") - } - defer os.RemoveAll(tmpDir) - log.Debug().Str("path", tmpDir).Msg("created temp dir") - - filesystemRoot := filepath.Join(tmpDir, "root") - if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create root dir") - } - orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "orbit") - if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create orbit dir") - } - - // Initialize autoupdate metadata - - updateOpt := update.DefaultOptions - updateOpt.Platform = "linux" - updateOpt.RootDirectory = orbitRoot - updateOpt.OrbitChannel = opt.OrbitChannel - updateOpt.OsqueryChannel = opt.OsqueryChannel - - // TODO these should be configurable - updateOpt.ServerURL = "https://tuf.fleetctl.com" - - if err := initializeUpdates(updateOpt); err != nil { - return errors.Wrap(err, "initialize updates") - } - - // Write files - - if err := writeSystemdUnit(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write systemd unit") - } - - if err := writeEnvFile(opt, filesystemRoot); err != nil { - return errors.Wrap(err, "write env file") - } - - postInstallPath := filepath.Join(tmpDir, "postinstall.sh") - if err := writePostInstall(opt, postInstallPath); err != nil { - return errors.Wrap(err, "write postinstall script") - } - - // Pick up all file contents - - contents := files.Contents{ - &files.Content{ - Source: filepath.Join(filesystemRoot, "**"), - Destination: "/", - }, - &files.Content{ - Source: "orbit", - Destination: "/var/lib/orbit/orbit", - FileInfo: &files.ContentFileInfo{ - Mode: constant.DefaultExecutableMode, - }, - }, - // Symlink current into /var/lib/orbit/bin/orbit/orbit - &files.Content{ - Source: "/var/lib/orbit/bin/orbit/linux/" + opt.OrbitChannel + "/orbit", - Destination: "/var/lib/orbit/bin/orbit/orbit", - Type: "symlink", - FileInfo: &files.ContentFileInfo{ - Mode: constant.DefaultExecutableMode | os.ModeSymlink, - }, - }, - // Symlink current into /usr/local/bin - &files.Content{ - Source: "/var/lib/orbit/bin/orbit/orbit", - Destination: "/usr/local/bin/orbit", - Type: "symlink", - FileInfo: &files.ContentFileInfo{ - Mode: constant.DefaultExecutableMode | os.ModeSymlink, - }, - }, - } - contents, err = files.ExpandContentGlobs(contents, false) - if err != nil { - return errors.Wrap(err, "glob contents") - } - for _, c := range contents { - log.Debug().Interface("file", c).Msg("added file") - } - - // Build package - - info := &nfpm.Info{ - Name: "orbit-osquery", - Version: opt.Version, - Description: "Orbit osquery -- runtime and autoupdater by Fleet", - Arch: "amd64", - Maintainer: "Fleet Engineers ", - Homepage: "https://github.com/fleetdm/orbit", - Overridables: nfpm.Overridables{ - Contents: contents, - EmptyFolders: []string{ - "/var/log/osquery", - "/var/log/orbit", - }, - Scripts: nfpm.Scripts{ - PostInstall: postInstallPath, - }, - }, - } - pkger := deb.Default - filename := pkger.ConventionalFileName(info) - - out, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode) - if err != nil { - return errors.Wrap(err, "open output file") - } - defer out.Close() - - if err := deb.Default.Package(info, out); err != nil { - return errors.Wrap(err, "write deb package") - } - log.Info().Str("path", filename).Msg("wrote deb package") - - return nil -} - -func writeSystemdUnit(opt Options, rootPath string) error { - systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system") - if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create systemd dir") - } - if err := ioutil.WriteFile( - filepath.Join(systemdRoot, "orbit.service"), - []byte(` -[Unit] -Description=Fleet Orbit osquery -After=network.service syslog.service -StartLimitIntervalSec=0 - -[Service] -TimeoutStartSec=0 -EnvironmentFile=/etc/default/orbit -ExecStart=/var/lib/orbit/bin/orbit/orbit -Restart=always -RestartSec=1 -KillMode=control-group -KillSignal=SIGTERM -CPUQuota=20% - -[Install] -WantedBy=multi-user.target -`), - constant.DefaultFileMode, - ); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - -var envTemplate = template.Must(template.New("env").Parse(` -{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} -{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} -{{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} -{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} -`)) - -func writeEnvFile(opt Options, rootPath string) error { - envRoot := filepath.Join(rootPath, "etc", "default") - if err := os.MkdirAll(envRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create env dir") - } - - var contents bytes.Buffer - if err := envTemplate.Execute(&contents, opt); err != nil { - return errors.Wrap(err, "execute template") - } - - if err := ioutil.WriteFile( - filepath.Join(envRoot, "orbit"), - contents.Bytes(), - constant.DefaultFileMode, - ); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - -var postInstallTemplate = template.Must(template.New("postinstall").Parse(` -#!/bin/sh - -# Exit on error -set -e - -# If we have a systemd, daemon-reload away now -if [ -x /bin/systemctl ] && pidof systemd ; then - /bin/systemctl daemon-reload 2>/dev/null 2>&1 -{{ if .StartService -}} - /bin/systemctl restart orbit.service 2>&1 -{{- end}} -fi -`)) - -func writePostInstall(opt Options, path string) error { - var contents bytes.Buffer - if err := postInstallTemplate.Execute(&contents, opt); err != nil { - return errors.Wrap(err, "execute template") - } - - if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { - return errors.Wrap(err, "write file") - } - - return nil + return buildNFPM(opt, deb.Default) } diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go new file mode 100644 index 0000000000..c1b7db1593 --- /dev/null +++ b/pkg/packaging/linux_shared.go @@ -0,0 +1,233 @@ +package packaging + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" + "text/template" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/update" + "github.com/goreleaser/nfpm/v2" + "github.com/goreleaser/nfpm/v2/files" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +func buildNFPM(opt Options, pkger nfpm.Packager) error { + // Initialize directories + + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "root") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create root dir") + } + orbitRoot := filepath.Join(filesystemRoot, "var", "lib", "orbit") + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + // Initialize autoupdate metadata + + updateOpt := update.DefaultOptions + updateOpt.Platform = "linux" + updateOpt.RootDirectory = orbitRoot + updateOpt.OrbitChannel = opt.OrbitChannel + updateOpt.OsqueryChannel = opt.OsqueryChannel + + // TODO these should be configurable + updateOpt.ServerURL = "https://tuf.fleetctl.com" + + if err := initializeUpdates(updateOpt); err != nil { + return errors.Wrap(err, "initialize updates") + } + + // Write files + + if err := writeSystemdUnit(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write systemd unit") + } + + if err := writeEnvFile(opt, filesystemRoot); err != nil { + return errors.Wrap(err, "write env file") + } + + postInstallPath := filepath.Join(tmpDir, "postinstall.sh") + if err := writePostInstall(opt, postInstallPath); err != nil { + return errors.Wrap(err, "write postinstall script") + } + + // Pick up all file contents + + contents := files.Contents{ + &files.Content{ + Source: filepath.Join(filesystemRoot, "**"), + Destination: "/", + }, + &files.Content{ + Source: "orbit", + Destination: "/var/lib/orbit/orbit", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode, + }, + }, + // Symlink current into /var/lib/orbit/bin/orbit/orbit + &files.Content{ + Source: "/var/lib/orbit/bin/orbit/linux/" + opt.OrbitChannel + "/orbit", + Destination: "/var/lib/orbit/bin/orbit/orbit", + Type: "symlink", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode | os.ModeSymlink, + }, + }, + // Symlink current into /usr/local/bin + &files.Content{ + Source: "/var/lib/orbit/bin/orbit/orbit", + Destination: "/usr/local/bin/orbit", + Type: "symlink", + FileInfo: &files.ContentFileInfo{ + Mode: constant.DefaultExecutableMode | os.ModeSymlink, + }, + }, + } + contents, err = files.ExpandContentGlobs(contents, false) + if err != nil { + return errors.Wrap(err, "glob contents") + } + for _, c := range contents { + log.Debug().Interface("file", c).Msg("added file") + } + + // Build package + + info := &nfpm.Info{ + Name: "orbit-osquery", + Version: opt.Version, + Description: "Orbit osquery -- runtime and autoupdater by Fleet", + Arch: "amd64", + Maintainer: "Fleet Engineers ", + Homepage: "https://github.com/fleetdm/orbit", + Overridables: nfpm.Overridables{ + Contents: contents, + EmptyFolders: []string{ + "/var/log/osquery", + "/var/log/orbit", + }, + Scripts: nfpm.Scripts{ + PostInstall: postInstallPath, + }, + }, + } + filename := pkger.ConventionalFileName(info) + + out, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, constant.DefaultFileMode) + if err != nil { + return errors.Wrap(err, "open output file") + } + defer out.Close() + + if err := pkger.Package(info, out); err != nil { + return errors.Wrap(err, "write package") + } + log.Info().Str("path", filename).Msg("wrote package") + + return nil +} + +func writeSystemdUnit(opt Options, rootPath string) error { + systemdRoot := filepath.Join(rootPath, "usr", "lib", "systemd", "system") + if err := os.MkdirAll(systemdRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create systemd dir") + } + if err := ioutil.WriteFile( + filepath.Join(systemdRoot, "orbit.service"), + []byte(` +[Unit] +Description=Orbit osquery +After=network.service syslog.service +StartLimitIntervalSec=0 + +[Service] +TimeoutStartSec=0 +EnvironmentFile=/etc/default/orbit +ExecStart=/var/lib/orbit/bin/orbit/orbit +Restart=always +RestartSec=1 +KillMode=control-group +KillSignal=SIGTERM +CPUQuota=20% + +[Install] +WantedBy=multi-user.target +`), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var envTemplate = template.Must(template.New("env").Parse(` +{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} +{{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} +{{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} +{{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} +`)) + +func writeEnvFile(opt Options, rootPath string) error { + envRoot := filepath.Join(rootPath, "etc", "default") + if err := os.MkdirAll(envRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create env dir") + } + + var contents bytes.Buffer + if err := envTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile( + filepath.Join(envRoot, "orbit"), + contents.Bytes(), + constant.DefaultFileMode, + ); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +var postInstallTemplate = template.Must(template.New("postinstall").Parse(` +#!/bin/sh + +# Exit on error +set -e + +# If we have a systemd, daemon-reload away now +if [ -x /bin/systemctl ] && pidof systemd ; then + /bin/systemctl daemon-reload 2>/dev/null 2>&1 +{{ if .StartService -}} + /bin/systemctl restart orbit.service 2>&1 +{{- end}} +fi +`)) + +func writePostInstall(opt Options, path string) error { + var contents bytes.Buffer + if err := postInstallTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), constant.DefaultFileMode); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/rpm.go b/pkg/packaging/rpm.go new file mode 100644 index 0000000000..ad62838ee5 --- /dev/null +++ b/pkg/packaging/rpm.go @@ -0,0 +1,7 @@ +package packaging + +import "github.com/goreleaser/nfpm/v2/rpm" + +func BuildRPM(opt Options) error { + return buildNFPM(opt, rpm.Default) +} From 8a13bfd22e46aaf2bc6a0d6f4459ca3ae5dc6ed0 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 12:46:57 -0800 Subject: [PATCH 066/115] Change launchctl restart mechanism - Don't `stop` before `unload` -- The job will attempt to restart - anyway. - Ensure job is enabled. --- pkg/packaging/macos_templates.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 361eeabf1a..fec960b5c9 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -37,12 +37,8 @@ ln -sf /var/lib/orbit/bin/orbit/macos/{{.OrbitChannel}}/orbit /var/lib/orbit/bin ln -sf /var/lib/orbit/bin/orbit/orbit /usr/local/bin/orbit {{ if .StartService -}} -launchctl stop com.fleetdm.orbit - -sleep 3 - launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist -launchctl load /Library/LaunchDaemons/com.fleetdm.orbit.plist +launchctl load -w /Library/LaunchDaemons/com.fleetdm.orbit.plist {{- end }} `)) From ad9f9be4116f420d5e0dcafa35a848bd9a7a9b04 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 15:22:17 -0800 Subject: [PATCH 067/115] Add debug flag support for packaging --- cmd/package/package.go | 7 ++++--- pkg/packaging/linux_shared.go | 1 + pkg/packaging/macos.go | 1 + pkg/packaging/macos_templates.go | 1 + pkg/packaging/packaging.go | 2 ++ 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index 0e06c6795e..f01e632143 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -77,12 +77,13 @@ func main() { Destination: &opt.Notarize, }, &cli.BoolFlag{ - Name: "debug", - Usage: "Enable debug logging", + Name: "debug", + Usage: "Enable debug logging", + Destination: &opt.Debug, }, } app.Before = func(c *cli.Context) error { - if c.Bool("debug") { + if opt.Debug { zerolog.SetGlobalLevel(zerolog.DebugLevel) } return nil diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index c1b7db1593..8e16c0373c 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -180,6 +180,7 @@ var envTemplate = template.Must(template.New("env").Parse(` {{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} +{{ if .Debug }}ORBIT_DEBUG=true{{ end }} `)) func writeEnvFile(opt Options, rootPath string) error { diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index bc4a4c9dae..a5f39a64b3 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -88,6 +88,7 @@ func BuildPkg(opt Options) error { // } // Build package + if err := xarBom(opt, tmpDir); err != nil { return errors.Wrap(err, "build pkg") } diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index fec960b5c9..762de464a7 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -69,6 +69,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} + {{ if .Debug }}ORBIT_DEBUGtrue{{ end }} KeepAlive RunAtLoad diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 3b59a03dca..15bf608110 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -38,6 +38,8 @@ type Options struct { OrbitChannel string // OsqueryChannel is the update channel to use for Osquery. OsqueryChannel string + // Debug determines whether to enable debug logging for the agent. + Debug bool } func copyFile(srcPath, dstPath string, perm os.FileMode) error { From f38206a927d98adbfe7a81d0834ce941c76991fe Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 15:36:57 -0800 Subject: [PATCH 068/115] Move shell to separate file --- cmd/orbit/orbit.go | 73 ------------------------------------- cmd/orbit/shell.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 73 deletions(-) create mode 100644 cmd/orbit/shell.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 75c1f9ae2f..b85665435c 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -309,76 +309,3 @@ func main() { log.Error().Err(err).Msg("") } } - -var shellCommand = &cli.Command{ - Name: "shell", - Aliases: []string{"osqueryi"}, - Usage: "Run the osqueryi shell", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "osquery-channel", - Usage: "Channel of osquery version to use", - Value: "stable", - EnvVars: []string{"ORBIT_OSQUERY_CHANNEL"}, - }, - &cli.BoolFlag{ - Name: "debug", - Usage: "Enable debug logging", - EnvVars: []string{"ORBIT_DEBUG"}, - }, - }, - Action: func(c *cli.Context) error { - if c.Bool("debug") { - zerolog.SetGlobalLevel(zerolog.DebugLevel) - } - - if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "initialize root dir") - } - - localStore, err := filestore.New(filepath.Join(c.String("root-dir"), "tuf-metadata.json")) - if err != nil { - log.Fatal().Err(err).Msg("failed to create local metadata store") - } - - // Initialize updater and get expected version - opt := update.DefaultOptions - opt.RootDirectory = c.String("root-dir") - opt.ServerURL = c.String("tuf-url") - opt.LocalStore = localStore - opt.InsecureTransport = c.Bool("insecure") - updater, err := update.New(opt) - if err != nil { - return err - } - if err := updater.UpdateMetadata(); err != nil { - log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") - } - osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) - if err != nil { - return err - } - - var g run.Group - - // Create an osquery runner with the provided options - r, _ := osquery.NewRunner( - osquerydPath, - osquery.WithShell(), - // Handle additional args after -- - osquery.WithFlags(c.Args().Slice()), - ) - g.Add(r.Execute, r.Interrupt) - - // Install a signal handler - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) - - if err := g.Run(); err != nil { - log.Error().Err(err).Msg("unexpected exit") - } - - return nil - }, -} diff --git a/cmd/orbit/shell.go b/cmd/orbit/shell.go new file mode 100644 index 0000000000..d89d5861b3 --- /dev/null +++ b/cmd/orbit/shell.go @@ -0,0 +1,90 @@ +package main + +import ( + "context" + "os" + "path/filepath" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/osquery" + "github.com/fleetdm/orbit/pkg/update" + "github.com/fleetdm/orbit/pkg/update/filestore" + "github.com/oklog/run" + "github.com/pkg/errors" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" + "github.com/urfave/cli/v2" +) + +var shellCommand = &cli.Command{ + Name: "shell", + Aliases: []string{"osqueryi"}, + Usage: "Run the osqueryi shell", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "osqueryd-channel", + Usage: "Channel of osqueryd version to use", + Value: "stable", + EnvVars: []string{"ORBIT_OSQUERYD_CHANNEL"}, + }, + &cli.BoolFlag{ + Name: "debug", + Usage: "Enable debug logging", + EnvVars: []string{"ORBIT_DEBUG"}, + }, + }, + Action: func(c *cli.Context) error { + if c.Bool("debug") { + zerolog.SetGlobalLevel(zerolog.DebugLevel) + } + + if err := os.MkdirAll(c.String("root-dir"), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize root dir") + } + + localStore, err := filestore.New(filepath.Join(c.String("root-dir"), "tuf-metadata.json")) + if err != nil { + log.Fatal().Err(err).Msg("failed to create local metadata store") + } + + // Initialize updater and get expected version + opt := update.DefaultOptions + opt.RootDirectory = c.String("root-dir") + opt.ServerURL = c.String("tuf-url") + opt.LocalStore = localStore + opt.InsecureTransport = c.Bool("insecure") + updater, err := update.New(opt) + if err != nil { + return err + } + if err := updater.UpdateMetadata(); err != nil { + log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") + } + osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) + if err != nil { + return err + } + + var g run.Group + + // Create an osquery runner with the provided options + r, _ := osquery.NewRunner( + osquerydPath, + osquery.WithShell(), + // Handle additional args after -- + osquery.WithFlags(c.Args().Slice()), + ) + g.Add(r.Execute, r.Interrupt) + + // Install a signal handler + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + g.Add(run.SignalHandler(ctx, os.Interrupt, os.Kill)) + + if err := g.Run(); err != nil { + log.Error().Err(err).Msg("unexpected exit") + } + + return nil + }, +} From aa562c3a52485fd45ce5bdf4f322ed5bce44d39b Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 15:37:11 -0800 Subject: [PATCH 069/115] Set default config_refresh in fleet flags This ensures we don't end up in a state where osquery does not check in for config updates. --- pkg/osquery/flags.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/osquery/flags.go b/pkg/osquery/flags.go index ca7376660e..f5abeb82cd 100644 --- a/pkg/osquery/flags.go +++ b/pkg/osquery/flags.go @@ -13,6 +13,10 @@ func FleetFlags(fleetURL *url.URL) []string { "--enroll_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/enroll"), "--config_plugin=tls", "--config_tls_endpoint=" + path.Join(prefix, "/api/v1/osquery/config"), + // Osquery defaults config_refresh to 0 which is probably not ideal for + // a client connected to Fleet. Users can always override this in the + // config they serve via Fleet. + "--config_refresh=60", "--disable_distributed=false", "--distributed_plugin=tls", "--distributed_tls_max_attempts=10", From d9839204c5b0ca2991eed0199df4071e589eb59a Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 15:40:27 -0800 Subject: [PATCH 070/115] Update README for .rpm package support --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04f98489cc..28419f5340 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,11 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autou | ------------------------------------ | ------ | | Secure autoupdate for osquery | ✅ | | Secure autoupdate for Orbit | ✅ | +| Configurable update channels | ✅ | | Full osquery flag customization | ✅ | | Package tooling for macOS `.pkg` | ✅ | | Package tooling for Linux `.deb` | ✅ | -| Package tooling for Linux `.rpm` | 🔜 | +| Package tooling for Linux `.rpm` | ✅ | | Package tooling for Windows `.msi` | 🔜 | | Manage/update osquery extensions | 🔜 | | Manage cgroups for Linux performance | 🔜 | From 45d99fc3b60c14891ff0c2aa3e1def558e6314e2 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 16:27:35 -0800 Subject: [PATCH 071/115] Add support for configuring update channels in packaging --- cmd/orbit/orbit.go | 14 +++++++------- cmd/package/package.go | 16 ++++++++++++---- pkg/packaging/linux_shared.go | 6 ++++-- pkg/packaging/macos.go | 2 +- pkg/packaging/macos_templates.go | 4 +++- pkg/packaging/packaging.go | 6 +++--- pkg/update/update.go | 6 +++--- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index b85665435c..e530fed471 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -82,16 +82,16 @@ func main() { EnvVars: []string{"ORBIT_ENROLL_SECRET_PATH"}, }, &cli.StringFlag{ - Name: "osquery-channel", - Usage: "Update channel of osquery to use", + Name: "osqueryd-channel", + Usage: "Update channel of osqueryd to use", Value: "stable", - EnvVars: []string{"ORBIT_OSQUERY_CHANNEL"}, + EnvVars: []string{"ORBIT_OSQUERYD_CHANNEL"}, }, &cli.StringFlag{ Name: "orbit-channel", - Usage: "Update channel of orbit to use", + Usage: "Update channel of Orbit to use", Value: "stable", - EnvVars: []string{"ORBI_ORBIT_CHANNEL"}, + EnvVars: []string{"ORBIT_ORBIT_CHANNEL"}, }, &cli.BoolFlag{ Name: "debug", @@ -155,7 +155,7 @@ func main() { if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) + osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-channel")) if err != nil { return err } @@ -165,7 +165,7 @@ func main() { updateRunner, err := update.NewRunner(updater, update.RunnerOptions{ CheckInterval: 10 * time.Second, Targets: map[string]string{ - "osqueryd": c.String("osquery-channel"), + "osqueryd": c.String("osqueryd-channel"), "orbit": c.String("orbit-channel"), }, }) diff --git a/cmd/package/package.go b/cmd/package/package.go index f01e632143..536006a1e8 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -76,6 +76,18 @@ func main() { Usage: "Whether to notarize macOS packages", Destination: &opt.Notarize, }, + &cli.StringFlag{ + Name: "osqueryd-channel", + Usage: "Update channel of osqueryd to use", + Value: "stable", + Destination: &opt.OsquerydChannel, + }, + &cli.StringFlag{ + Name: "orbit-channel", + Usage: "Update channel of Orbit to use", + Value: "stable", + Destination: &opt.OrbitChannel, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", @@ -99,10 +111,6 @@ func main() { return errors.New("--insecure and --fleet-certificate may not be provided together") } - // TODO take these from flags - opt.OrbitChannel = "stable" - opt.OsqueryChannel = "stable" - switch c.String("type") { case "pkg": return packaging.BuildPkg(opt) diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index 8e16c0373c..b7d04a7d6d 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -40,7 +40,7 @@ func buildNFPM(opt Options, pkger nfpm.Packager) error { updateOpt.Platform = "linux" updateOpt.RootDirectory = orbitRoot updateOpt.OrbitChannel = opt.OrbitChannel - updateOpt.OsqueryChannel = opt.OsqueryChannel + updateOpt.OsquerydChannel = opt.OsquerydChannel // TODO these should be configurable updateOpt.ServerURL = "https://tuf.fleetctl.com" @@ -176,7 +176,9 @@ WantedBy=multi-user.target } var envTemplate = template.Must(template.New("env").Parse(` -{{- if .Insecure }}ORBIT_INSECURE=true{{ end }} +ORBIT_ORBIT_CHANNEL={{ .OrbitChannel }} +ORBIT_OSQUERYD_CHANNEL={{ .OsquerydChannel }} +{{ if .Insecure }}ORBIT_INSECURE=true{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL={{.FleetURL}}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE=/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET={{.EnrollSecret}}{{ end }} diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index a5f39a64b3..77d969d50c 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -44,7 +44,7 @@ func BuildPkg(opt Options) error { updateOpt.Platform = "macos" updateOpt.RootDirectory = orbitRoot updateOpt.OrbitChannel = opt.OrbitChannel - updateOpt.OsqueryChannel = opt.OsqueryChannel + updateOpt.OsquerydChannel = opt.OsquerydChannel // TODO these should be configurable updateOpt.ServerURL = "https://tuf.fleetctl.com" diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 762de464a7..2ea64fb2b8 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -65,8 +65,10 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err /var/log/orbit/orbit.stderr.log EnvironmentVariables + ORBIT_ORBIT_CHANNEL{{ .OrbitChannel }} + ORBIT_OSQUERYD_CHANNEL{{ .OsquerydChannel }} {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} - {{ if .FleetURL }}ORBIT_FLEET_URL{{.FleetURL}}{{ end }} + {{ if .FleetURL }}ORBIT_FLEET_URL{{ .FleetURL }}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} {{ if .Debug }}ORBIT_DEBUGtrue{{ end }} diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 15bf608110..15fd3016bf 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -36,8 +36,8 @@ type Options struct { FleetCertificate string // OrbitChannel is the update channel to use for Orbit. OrbitChannel string - // OsqueryChannel is the update channel to use for Osquery. - OsqueryChannel string + // OsquerydChannel is the update channel to use for Osquery (osqueryd). + OsquerydChannel string // Debug determines whether to enable debug logging for the agent. Debug bool } @@ -80,7 +80,7 @@ func initializeUpdates(updateOpt update.Options) error { if err := updater.UpdateMetadata(); err != nil { return errors.Wrap(err, "failed to update metadata") } - osquerydPath, err := updater.Get("osqueryd", updateOpt.OsqueryChannel) + osquerydPath, err := updater.Get("osqueryd", updateOpt.OsquerydChannel) if err != nil { return errors.Wrap(err, "failed to get osqueryd") } diff --git a/pkg/update/update.go b/pkg/update/update.go index 9ee33d5716..46301829a4 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -48,8 +48,8 @@ type Options struct { Platform string // OrbitChannel is the update channel to use for Orbit. OrbitChannel string - // OsqueryChannel is the update channel to use for Osquery. - OsqueryChannel string + // OsquerydChannel is the update channel to use for osquery (osqueryd). + OsquerydChannel string } var ( @@ -63,7 +63,7 @@ var ( Platform: constant.PlatformName, RootKeys: defaultRootKeys, OrbitChannel: "stable", - OsqueryChannel: "stable", + OsquerydChannel: "stable", } ) From b1b6017a26392392dc2d7621df9f1b3a5df6a861 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 9 Mar 2021 16:36:34 -0800 Subject: [PATCH 072/115] Update packaging information --- README.md | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 28419f5340..8fb294b2a2 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,69 @@ orbit -- --flagfile=flags.txt ## Packaging -TODO +Orbit, like standalone osquery, is typically deployed via OS-specific packages. Tooling is provided with this repository to generate installation packages. + +### Packaging support + +- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) - Persistence via `launchd`. + +- **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. + +- **Windows** (coming soon) - `.msi` package generation - Persistence via Services. + +### Building packages + +Before building packages, clone or download this repository and [install Go](https://golang.org/doc/install). + +Use `go run ./cmd/package` from this directory to run the packaging tools. + +The only required parameter is `--type`, use one of `deb`, `rpm`, or `pkg` (`msi` coming soon). + +Configure osquery to connect to a Fleet (or other TLS) server with the `--fleet-url` and `--enroll-secret` flags. + +A minimal invocation for communicating with Fleet: + +``` sh +go run ./cmd/package --type deb --fleet-url=test.fleetdm.com --enroll-secret=notsosecret +``` + +This will build a `.deb` package configured to communicate with a Fleet server at `test.fleetdm.com` using the enroll secret `notsosecret`. + +When the Fleet server uses a self-signed (or otherwise invalid) TLS certificate, package with the `--insecure` or `--fleet-certificate` options. + +See `go run ./cmd/package` for the full range of packaging options. + +#### Update channels + +Orbit uses the concept of "update channels" to determine the version of Orbit, osquery, and any extensions (extension support coming soon) to run. This concept is modeled from the common versioning convention for Docker containers. + +Configure update channels for Orbit and osqueryd with the `--orbit-channel` and `--osqueryd-channel` flags when packaging. + +| Channel | Versions | +| ------------------------------------ | ------ | +| `4` | 4.x.x | +| `4.6` | 4.6.x | +| `4.6.0` | 4.6.0 | + +Additionally `stable` and `edge` are special channel names. `stable` will always return the version Fleet deems to be stable, while `edge` will provide newer releases for beta testing. + +#### macOS signing & Notarization + +Orbit's packager can automate the codesigning and Notarization steps to allow the resulting package to generate packages that appear "trusted" when install on macOS hosts. Signing & notarization are supported only on macOS hosts. + +For signing, a "Developer ID Installer" certificate must be available on the build machine ([generation instructions](https://help.apple.com/xcode/mac/current/#/dev154b28f09)). Use `security find-identity -v` to verify the existence of this certificate and make note of the identifier provided in the left column. + +For Notarization, valid App Store Connect credentials must be available on the build machine. Set these in the environment variables `AC_USERNAME` and `AC_PASSWORD`. It is common to configure this via [app-specific passwords](https://support.apple.com/en-ca/HT204397). + +Build a signed and notarized macOS package with an invocation like the following: + +``` sh +AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type pkg --fleet-url=test.fleetdm.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize +``` + +This process may take several minutes to complete as the Notarization process completes on Apple's servers. + +After successful notarization, the generated "ticket" is automatically stapled to the package. ## FAQs From 2be04d0bd8200fc69093ba096c271f11058fe28d Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Wed, 10 Mar 2021 11:45:47 -0600 Subject: [PATCH 073/115] quickstart (first draft) (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * quickstart (first draft) * test.fleetdm.com » fleet.example.com --- README.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8fb294b2a2..614df5068f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,21 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autoupdater. With Orbit, it's easy to deploy osquery, manage configurations, and stay up to date. Orbit eases the deployment of osquery connected with a [Fleet server](https://github.com/fleetdm/fleet), and is a (near) drop-in replacement for osquery in a variety of deployment scenarios. +## Try Orbit + +#### With [`fleetctl preview` already running](https://github.com/fleetdm/fleet) and [Go](https://golang.org/doc/install) installed: + +```bash +# From within the top-level directory of this repo… +# Generate a macOS installer pointed at your local Fleet +go run ./cmd/package --type=pkg --fleet-url=localhost:8412 --insecure --enroll-secret=YOUR_FLEET_ENROLL_SECRET_HERE +``` + +An installer configured to point at your Fleet instance has now been generated. + +Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. In Fleet, after several seconds, you should now see your local computer as a new host. + + ## Capabilities | Capability | Status | @@ -98,10 +113,10 @@ Configure osquery to connect to a Fleet (or other TLS) server with the `--fleet- A minimal invocation for communicating with Fleet: ``` sh -go run ./cmd/package --type deb --fleet-url=test.fleetdm.com --enroll-secret=notsosecret +go run ./cmd/package --type deb --fleet-url=fleet.example.com --enroll-secret=notsosecret ``` -This will build a `.deb` package configured to communicate with a Fleet server at `test.fleetdm.com` using the enroll secret `notsosecret`. +This will build a `.deb` package configured to communicate with a Fleet server at `fleet.example.com` using the enroll secret `notsosecret`. When the Fleet server uses a self-signed (or otherwise invalid) TLS certificate, package with the `--insecure` or `--fleet-certificate` options. @@ -132,7 +147,7 @@ For Notarization, valid App Store Connect credentials must be available on the b Build a signed and notarized macOS package with an invocation like the following: ``` sh -AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type pkg --fleet-url=test.fleetdm.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize +AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type pkg --fleet-url=fleet.example.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize ``` This process may take several minutes to complete as the Notarization process completes on Apple's servers. From 77cecd87ac8494beffd33f7162e8072cc30dc73c Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 10 Mar 2021 10:54:32 -0800 Subject: [PATCH 074/115] Improve link to try fleet --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 614df5068f..97589790a0 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autou ## Try Orbit -#### With [`fleetctl preview` already running](https://github.com/fleetdm/fleet) and [Go](https://golang.org/doc/install) installed: +#### With [`fleetctl preview` already running](https://github.com/fleetdm/fleet#try-fleet) and [Go](https://golang.org/doc/install) installed: ```bash # From within the top-level directory of this repo… From 24f9a4c4d82802611fd732de7eb45711537eba64 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 10 Mar 2021 14:40:20 -0800 Subject: [PATCH 075/115] Update signing cert and notarization username --- .gon.hcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gon.hcl b/.gon.hcl index 9c59a9e151..4e39c9980e 100644 --- a/.gon.hcl +++ b/.gon.hcl @@ -2,11 +2,11 @@ source = ["./dist/macos_darwin_amd64/orbit"] bundle_id = "com.fleetdm.orbit" apple_id { - username = "zach@fleetdm.com" + username = "@env:AC_USERNAME" password = "@env:AC_PASSWORD" } sign { - application_identity = "D208111AA5D441DE07993F833E1F36F67526F489" + application_identity = "51049B247B25B3119FAE7E9C0CC4375A43E47237" } From f5792a07468a692598eee70c265d85fb5c87a9d1 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 10 Mar 2021 14:42:02 -0800 Subject: [PATCH 076/115] Make update server URL configurable Configurable in both packaging and orbit invocations --- cmd/orbit/orbit.go | 9 ++++----- cmd/package/package.go | 6 ++++++ pkg/packaging/linux_shared.go | 5 ++--- pkg/packaging/macos.go | 4 +--- pkg/packaging/macos_templates.go | 1 + pkg/packaging/packaging.go | 2 ++ pkg/update/update.go | 5 +++-- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index e530fed471..c41f6bfaab 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -26,7 +26,6 @@ import ( ) const ( - tufURL = "https://tuf.fleetctl.com" certPath = "/tmp/fleet.pem" defaultRootDir = "/var/lib/orbit" ) @@ -66,10 +65,10 @@ func main() { EnvVars: []string{"ORBIT_FLEET_CERTIFICATE"}, }, &cli.StringFlag{ - Name: "tuf-url", - Usage: "URL of TUF update server", - Value: tufURL, - EnvVars: []string{"ORBIT_TUF_URL"}, + Name: "update-url", + Usage: "URL for update server", + Value: "https://tuf.fleetctl.com", + EnvVars: []string{"ORBIT_UPDATE_URL"}, }, &cli.StringFlag{ Name: "enroll-secret", diff --git a/cmd/package/package.go b/cmd/package/package.go index 536006a1e8..1401292f3f 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -88,6 +88,12 @@ func main() { Value: "stable", Destination: &opt.OrbitChannel, }, + &cli.StringFlag{ + Name: "update-url", + Usage: "URL for update server", + Value: "https://tuf.fleetctl.com", + Destination: &opt.UpdateURL, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index b7d04a7d6d..a231863026 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -41,9 +41,7 @@ func buildNFPM(opt Options, pkger nfpm.Packager) error { updateOpt.RootDirectory = orbitRoot updateOpt.OrbitChannel = opt.OrbitChannel updateOpt.OsquerydChannel = opt.OsquerydChannel - - // TODO these should be configurable - updateOpt.ServerURL = "https://tuf.fleetctl.com" + updateOpt.ServerURL = opt.UpdateURL if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") @@ -176,6 +174,7 @@ WantedBy=multi-user.target } var envTemplate = template.Must(template.New("env").Parse(` +ORBIT_UPDATE_URL={{ .UpdateURL }} ORBIT_ORBIT_CHANNEL={{ .OrbitChannel }} ORBIT_OSQUERYD_CHANNEL={{ .OsquerydChannel }} {{ if .Insecure }}ORBIT_INSECURE=true{{ end }} diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 77d969d50c..35a7f16ec8 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -45,9 +45,7 @@ func BuildPkg(opt Options) error { updateOpt.RootDirectory = orbitRoot updateOpt.OrbitChannel = opt.OrbitChannel updateOpt.OsquerydChannel = opt.OsquerydChannel - - // TODO these should be configurable - updateOpt.ServerURL = "https://tuf.fleetctl.com" + updateOpt.ServerURL = opt.UpdateURL if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 2ea64fb2b8..6c4019e1a1 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -65,6 +65,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err /var/log/orbit/orbit.stderr.log EnvironmentVariables + ORBIT_UPDATE_URL{{ .UpdateURL }} ORBIT_ORBIT_CHANNEL{{ .OrbitChannel }} ORBIT_OSQUERYD_CHANNEL{{ .OsquerydChannel }} {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 15fd3016bf..94abb2adf4 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -38,6 +38,8 @@ type Options struct { OrbitChannel string // OsquerydChannel is the update channel to use for Osquery (osqueryd). OsquerydChannel string + // UpdateURL is the base URL of the update server (TUF repository). + UpdateURL string // Debug determines whether to enable debug logging for the agent. Debug bool } diff --git a/pkg/update/update.go b/pkg/update/update.go index 46301829a4..5069d0156a 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -20,6 +20,7 @@ import ( const ( binDir = "bin" + defaultURL = "https://tuf.fleetctl.com" defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"037b475337c1acdafe20cff4fee6308209bc4ba23a2439a1f7be85131794cae1"}}]` ) @@ -57,11 +58,11 @@ var ( // client. DefaultOptions = Options{ RootDirectory: "/var/lib/orbit", - ServerURL: "https://tuf.fleetctl.com", + ServerURL: defaultURL, + RootKeys: defaultRootKeys, LocalStore: client.MemoryLocalStore(), InsecureTransport: false, Platform: constant.PlatformName, - RootKeys: defaultRootKeys, OrbitChannel: "stable", OsquerydChannel: "stable", } From be596e0949a21a97b58a3453a11a182e0b3a433b Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 10 Mar 2021 18:45:13 -0800 Subject: [PATCH 077/115] Add new trust root for production TUF repo --- pkg/update/update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/update/update.go b/pkg/update/update.go index 5069d0156a..3178aa5ddc 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -21,7 +21,7 @@ const ( binDir = "bin" defaultURL = "https://tuf.fleetctl.com" - defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"037b475337c1acdafe20cff4fee6308209bc4ba23a2439a1f7be85131794cae1"}}]` + defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"6d71d3beac3b830be929f2b10d513448d49ec6bb62a680176b89ffdfca180eb4"}}]` ) // Updater is responsible for managing update state. From be6a28231586fd5fe85163ca5c9aa8cd5d07d641 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 10 Mar 2021 19:21:00 -0800 Subject: [PATCH 078/115] Add version command and flag --- .gon.hcl | 2 +- .goreleaser.yml | 13 +++---------- cmd/orbit/orbit.go | 29 +++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/.gon.hcl b/.gon.hcl index 4e39c9980e..f37941c2db 100644 --- a/.gon.hcl +++ b/.gon.hcl @@ -1,4 +1,4 @@ -source = ["./dist/macos_darwin_amd64/orbit"] +source = ["./dist/orbit_darwin_amd64/orbit"] bundle_id = "com.fleetdm.orbit" apple_id { diff --git a/.goreleaser.yml b/.goreleaser.yml index ce36ff4b0f..e293cdfba3 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -8,18 +8,11 @@ builds: goos: - linux - windows - goarch: - - amd64 - dir: ./cmd/orbit/ - binary: orbit - - - id: macos - env: - - CGO_ENABLED=0 - goos: - darwin goarch: - amd64 + ldflags: + - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser dir: ./cmd/orbit/ binary: orbit @@ -32,7 +25,7 @@ archives: signs: - signature: "${artifact}_macos.dmg" ids: - - macos + - orbit cmd: gon args: - .gon.hcl diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index c41f6bfaab..77c867ec5c 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -30,6 +30,13 @@ const ( defaultRootDir = "/var/lib/orbit" ) +var ( + // Flags set by goreleaser during build + version = "" + commit = "" + date = "" +) + func main() { log.Logger = log.Output( zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, @@ -40,6 +47,7 @@ func main() { app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" app.Commands = []*cli.Command{ + versionCommand, shellCommand, } app.Flags = []cli.Flag{ @@ -97,8 +105,17 @@ func main() { Usage: "Enable debug logging", EnvVars: []string{"ORBIT_DEBUG"}, }, + &cli.BoolFlag{ + Name: "version", + Usage: "Get Orbit version", + }, } app.Action = func(c *cli.Context) error { + if c.Bool("version") { + fmt.Println("orbit " + version) + return nil + } + if c.Bool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) } @@ -308,3 +325,15 @@ func main() { log.Error().Err(err).Msg("") } } + +var versionCommand = &cli.Command{ + Name: "version", + Usage: "Get the orbit version", + Flags: []cli.Flag{}, + Action: func(c *cli.Context) error { + fmt.Println("orbit " + version) + fmt.Println("commit - " + commit) + fmt.Println("date - " + date) + return nil + }, +} From 6c4c6e3c6154bad386986cfbc627e5b3bf9ca966 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 11 Mar 2021 09:50:53 -0800 Subject: [PATCH 079/115] Update goreleaser configuration Add signing, separate archives, release configuration --- .gon.hcl | 12 -------- .goreleaser.yml | 64 +++++++++++++++++++++++++++++---------- tools/build/sign-macos.sh | 25 +++++++++++++++ 3 files changed, 73 insertions(+), 28 deletions(-) delete mode 100644 .gon.hcl create mode 100755 tools/build/sign-macos.sh diff --git a/.gon.hcl b/.gon.hcl deleted file mode 100644 index f37941c2db..0000000000 --- a/.gon.hcl +++ /dev/null @@ -1,12 +0,0 @@ -source = ["./dist/orbit_darwin_amd64/orbit"] -bundle_id = "com.fleetdm.orbit" - -apple_id { - username = "@env:AC_USERNAME" - password = "@env:AC_PASSWORD" -} - -sign { - application_identity = "51049B247B25B3119FAE7E9C0CC4375A43E47237" -} - diff --git a/.goreleaser.yml b/.goreleaser.yml index e293cdfba3..319f7cae68 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -3,33 +3,58 @@ before: - go mod download builds: - - env: + - id: orbit + dir: ./cmd/orbit/ + binary: orbit + env: - CGO_ENABLED=0 goos: + - darwin - linux - windows - - darwin goarch: - amd64 ldflags: - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser - dir: ./cmd/orbit/ - binary: orbit + hooks: + post: ./tools/build/sign-macos.sh {{ .Path }} + + - id: orbit-package + dir: ./cmd/package/ + binary: orbit-package + env: + - CGO_ENABLED=0 + goos: + - darwin + - linux + - windows + goarch: + - amd64 + ldflags: + - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser + hooks: + post: ./tools/build/sign-macos.sh {{ .Path }} archives: - - replacements: - darwin: macos - 386: i386 - amd64: x86_64 - -signs: - - signature: "${artifact}_macos.dmg" - ids: + - id: orbit + builds: - orbit - cmd: gon - args: - - .gon.hcl - artifacts: all + name_template: orbit_{{.Version}}_{{.Os}} + replacements: + darwin: macos + format_overrides: + - goos: windows + format: zip + + - id: orbit-package + builds: + - orbit-package + name_template: orbit-package_{{.Version}}_{{.Os}} + replacements: + darwin: macos + format_overrides: + - goos: windows + format: zip checksum: name_template: 'checksums.txt' @@ -38,8 +63,15 @@ snapshot: name_template: "{{ .Tag }}-untagged" changelog: + skip: true sort: asc filters: exclude: - '^docs:' - '^test:' + +release: + github: + owner: fleetdm + name: orbit + draft: true diff --git a/tools/build/sign-macos.sh b/tools/build/sign-macos.sh new file mode 100755 index 0000000000..17b02b6c5f --- /dev/null +++ b/tools/build/sign-macos.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -eo pipefail + +if [ -z "$CODESIGN_IDENTITY" ] +then + echo 'Must set CODESIGN_IDENTITY in environment' + exit 1 +fi + +if [ ! -f "$1" ] +then + echo 'First argument must be path to binary' + exit 1 +fi + +# Skip if not a macOS Mach-O executable +if ! ( file "$1" | grep Mach-O ) +then + echo 'Skip macOS signing' + exit 0 +fi + +codesign -s "$CODESIGN_IDENTITY" -i com.fleetdm.orbit -f -v --timestamp --options runtime "$1" + +echo "Signed successfully" From 579ff1550675ed945f5082a07167a0dd95ac3c67 Mon Sep 17 00:00:00 2001 From: noahtalerman <47070608+noahtalerman@users.noreply.github.com> Date: Thu, 11 Mar 2021 11:55:08 -0800 Subject: [PATCH 080/115] Add enroll secret section (#4) --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97589790a0..5df4e6278f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autou # Generate a macOS installer pointed at your local Fleet go run ./cmd/package --type=pkg --fleet-url=localhost:8412 --insecure --enroll-secret=YOUR_FLEET_ENROLL_SECRET_HERE ``` +> With fleetctl preview running, you can find your Fleet enroll secret by selecting the "Add new host" button on the Hosts page in the Fleet UI. An installer configured to point at your Fleet instance has now been generated. @@ -147,7 +148,7 @@ For Notarization, valid App Store Connect credentials must be available on the b Build a signed and notarized macOS package with an invocation like the following: ``` sh -AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type pkg --fleet-url=fleet.example.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize +AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type=pkg --fleet-url=fleet.example.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize ``` This process may take several minutes to complete as the Notarization process completes on Apple's servers. From cf940ea0cfcd3e57824241c14f52a19fc1d53280 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 11 Mar 2021 14:11:52 -0600 Subject: [PATCH 081/115] Update README.md (#6) --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5df4e6278f..8426badecb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ # Orbit osquery -Orbit is Fleet's [osquery](https://github.com/osquery/osquery) runtime and autoupdater. With Orbit, it's easy to deploy osquery, manage configurations, and stay up to date. Orbit eases the deployment of osquery connected with a [Fleet server](https://github.com/fleetdm/fleet), and is a (near) drop-in replacement for osquery in a variety of deployment scenarios. +Orbit is an [osquery](https://github.com/osquery/osquery) runtime and autoupdater. With Orbit, it's easy to deploy osquery, manage configurations, and stay up to date. Orbit eases the deployment of osquery connected with a [Fleet server](https://github.com/fleetdm/fleet), and is a (near) drop-in replacement for osquery in a variety of deployment scenarios. + +Orbit is the recommended agent for Fleet. But Orbit can be used with or without Fleet, and Fleet can be used with or without Orbit. ## Try Orbit From 835f22a6ab49503380fc4d1e698f69b3d07c6004 Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 11 Mar 2021 14:17:23 -0600 Subject: [PATCH 082/115] add link to report bugs (#7) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8426badecb..06b10ba141 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ An installer configured to point at your Fleet instance has now been generated. Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. In Fleet, after several seconds, you should now see your local computer as a new host. +## Bugs +To report a bug or request a feature, [click here](https://github.com/fleetdm/fleet/issues). ## Capabilities From 705d6bb2e9369fdb0b541499fd8fae11d9a83dec Mon Sep 17 00:00:00 2001 From: Mike McNeil Date: Thu, 11 Mar 2021 14:32:46 -0600 Subject: [PATCH 083/115] add 30s recommendation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06b10ba141..3abd1060c0 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ go run ./cmd/package --type=pkg --fleet-url=localhost:8412 --insecure --enroll-s An installer configured to point at your Fleet instance has now been generated. -Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. In Fleet, after several seconds, you should now see your local computer as a new host. +Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. Refresh after several seconds (≈30s), and you should now see your local computer as a new host in Fleet. ## Bugs To report a bug or request a feature, [click here](https://github.com/fleetdm/fleet/issues). From ae39d9339bbadcd6de2be4cae750a82a62ae4f4d Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 11 Mar 2021 12:48:29 -0800 Subject: [PATCH 084/115] Fix loading of update URL from flag --- cmd/orbit/orbit.go | 2 +- cmd/orbit/shell.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 77c867ec5c..649cde203a 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -161,7 +161,7 @@ func main() { // Initialize updater and get expected version opt := update.DefaultOptions opt.RootDirectory = c.String("root-dir") - opt.ServerURL = c.String("tuf-url") + opt.ServerURL = c.String("update-url") opt.LocalStore = localStore opt.InsecureTransport = c.Bool("insecure") updater, err := update.New(opt) diff --git a/cmd/orbit/shell.go b/cmd/orbit/shell.go index d89d5861b3..9c92b288ff 100644 --- a/cmd/orbit/shell.go +++ b/cmd/orbit/shell.go @@ -50,7 +50,7 @@ var shellCommand = &cli.Command{ // Initialize updater and get expected version opt := update.DefaultOptions opt.RootDirectory = c.String("root-dir") - opt.ServerURL = c.String("tuf-url") + opt.ServerURL = c.String("update-url") opt.LocalStore = localStore opt.InsecureTransport = c.Bool("insecure") updater, err := update.New(opt) From 42a781dc2dc421479f76a3299ad23409f936845c Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 11 Mar 2021 13:01:17 -0800 Subject: [PATCH 085/115] Fix Linux packaging We no longer pull the Orbit file from the local fileystem. --- pkg/packaging/linux_shared.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index a231863026..2911e7625f 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -69,13 +69,6 @@ func buildNFPM(opt Options, pkger nfpm.Packager) error { Source: filepath.Join(filesystemRoot, "**"), Destination: "/", }, - &files.Content{ - Source: "orbit", - Destination: "/var/lib/orbit/orbit", - FileInfo: &files.ContentFileInfo{ - Mode: constant.DefaultExecutableMode, - }, - }, // Symlink current into /var/lib/orbit/bin/orbit/orbit &files.Content{ Source: "/var/lib/orbit/bin/orbit/linux/" + opt.OrbitChannel + "/orbit", From 39b01ef7dccaddaeb6d0ff8378241aa6cfc67def Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 11 Mar 2021 13:02:19 -0800 Subject: [PATCH 086/115] Update .gitignore --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 155860f1fb..e6f6a9c648 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,10 @@ tmp/ # Output of the go coverage tool, specifically when used with LiteIDE *.out + +# Build/packaging results +dist/ +*.pkg +*.deb +*.rpm +*.msi From 995c8b18e0f99f690ddf4d3782984af1d7c5f18c Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 11 Mar 2021 13:29:38 -0800 Subject: [PATCH 087/115] Make installer text more helpful If a user hits the "Customize" button they will now see helpful text rather than a nearly empty page. --- pkg/packaging/macos_templates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index 6c4019e1a1..a0420cb171 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -23,7 +23,7 @@ var macosDistributionTemplate = template.Must(template.New("").Option("missingke - + #base.pkg From adcae024099a7c7843b787c85d0f3b17864c347b Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Mar 2021 11:01:15 -0700 Subject: [PATCH 088/115] Update Launcher difference README Indicate that Orbit shares no code with Launcher --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3abd1060c0..e9876eaee1 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ After successful notarization, the generated "ticket" is automatically stapled t ### How does Orbit compare with Kolide Launcher? -Orbit is inspired by the success of [Kolide Launcher](https://github.com/kolide/launcher), and approaches a similar problem domain with new strategies informed by the challenges encountered in real world deployments. +Orbit is inspired by the success of [Kolide Launcher](https://github.com/kolide/launcher), and approaches a similar problem domain with new strategies informed by the challenges encountered in real world deployments. Orbit does not share any code with Launcher. - Both Orbit and Launcher use [The Update Framework](https://theupdateframework.com/) specification for managing updates. Orbit utilizes the official [go-tuf](https://github.com/theupdateframework/go-tuf) library, while Launcher has it's own implementation of the specification. - Orbit can be deployed as a (near) drop-in replacement for osquery, supporting full customization of the osquery flags. Launcher heavily manages the osquery flags making deployment outside of Fleet or Kolide's SaaS difficult. From de5b4f7a6a859bb7916f1d8afe3692036fb22d31 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Mar 2021 17:38:32 -0700 Subject: [PATCH 089/115] Take update root keys as a packaging flag (#8) This allows specifying the root key metadata which was the remaining requirement to allow working with a self-hosted update server. --- README.md | 3 ++- cmd/package/package.go | 7 ++++++- pkg/packaging/linux_shared.go | 3 +++ pkg/packaging/macos.go | 3 +++ pkg/packaging/packaging.go | 2 ++ 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e9876eaee1..c9910647c4 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,8 @@ Orbit, like standalone osquery, is typically deployed via OS-specific packages. ### Packaging support -- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) - Persistence via `launchd`. +- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) and codesigning. +- Persistence via `launchd`. - **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. diff --git a/cmd/package/package.go b/cmd/package/package.go index 1401292f3f..b2521f2d78 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -68,7 +68,7 @@ func main() { }, &cli.StringFlag{ Name: "sign-identity", - Usage: "Identity to use for codesigning", + Usage: "Identity to use for macOS codesigning", Destination: &opt.SignIdentity, }, &cli.BoolFlag{ @@ -94,6 +94,11 @@ func main() { Value: "https://tuf.fleetctl.com", Destination: &opt.UpdateURL, }, + &cli.StringFlag{ + Name: "update-roots", + Usage: "Root key JSON metadata for update server (from fleetctl updates roots)", + Destination: &opt.UpdateRoots, + }, &cli.BoolFlag{ Name: "debug", Usage: "Enable debug logging", diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index 2911e7625f..d1ccc8ab42 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -42,6 +42,9 @@ func buildNFPM(opt Options, pkger nfpm.Packager) error { updateOpt.OrbitChannel = opt.OrbitChannel updateOpt.OsquerydChannel = opt.OsquerydChannel updateOpt.ServerURL = opt.UpdateURL + if opt.UpdateRoots != "" { + updateOpt.RootKeys = opt.UpdateRoots + } if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 35a7f16ec8..96eb12a5b7 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -46,6 +46,9 @@ func BuildPkg(opt Options) error { updateOpt.OrbitChannel = opt.OrbitChannel updateOpt.OsquerydChannel = opt.OsquerydChannel updateOpt.ServerURL = opt.UpdateURL + if opt.UpdateRoots != "" { + updateOpt.RootKeys = opt.UpdateRoots + } if err := initializeUpdates(updateOpt); err != nil { return errors.Wrap(err, "initialize updates") diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 94abb2adf4..a12ef7954e 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -40,6 +40,8 @@ type Options struct { OsquerydChannel string // UpdateURL is the base URL of the update server (TUF repository). UpdateURL string + // UpdateRoots is the root JSON metadata for update server (TUF repository). + UpdateRoots string // Debug determines whether to enable debug logging for the agent. Debug bool } From e37995f28dfa72b7060a9ebd4e703e145d1db58f Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 22 Mar 2021 17:52:07 -0700 Subject: [PATCH 090/115] Fix documentation formatting for macOS persistence (#9) --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index c9910647c4..df9e5d1953 100644 --- a/README.md +++ b/README.md @@ -99,8 +99,7 @@ Orbit, like standalone osquery, is typically deployed via OS-specific packages. ### Packaging support -- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) and codesigning. -- Persistence via `launchd`. +- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) and codesigning - Persistence via `launchd`. - **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. From 7767da94e87c7559b03eeb41a04218fd46f34468 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 16 Apr 2021 17:08:02 -0700 Subject: [PATCH 091/115] Initial Windows support (#10) This commit adds support for Orbit's update and osquery execution capabilities on Windows. Still to come is the packaging tooling for building MSIs on Windows. --- cmd/orbit/orbit.go | 18 ++++- cmd/package/package.go | 4 +- pkg/database/database.go | 22 +++++- pkg/packaging/macos.go | 14 ---- pkg/packaging/macos_templates.go | 2 +- pkg/packaging/packaging.go | 16 ++++ pkg/packaging/windows.go | 104 ++++++++++++++++++++++++++ pkg/packaging/windows_templates.go | 78 ++++++++++++++++++++ pkg/packaging/wix/transform.go | 113 +++++++++++++++++++++++++++++ pkg/packaging/wix/wix.go | 88 ++++++++++++++++++++++ 10 files changed, 438 insertions(+), 21 deletions(-) create mode 100644 pkg/packaging/windows.go create mode 100644 pkg/packaging/windows_templates.go create mode 100644 pkg/packaging/wix/transform.go create mode 100644 pkg/packaging/wix/wix.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 649cde203a..0106eecf73 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/dgraph-io/badger/v2" "github.com/fleetdm/orbit/pkg/certificate" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" @@ -26,7 +27,6 @@ import ( ) const ( - certPath = "/tmp/fleet.pem" defaultRootDir = "/var/lib/orbit" ) @@ -143,9 +143,18 @@ func main() { return errors.Wrap(err, "initialize root dir") } - db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) + dbPath := filepath.Join(c.String("root-dir"), "orbit.db") + db, err := database.Open(dbPath) if err != nil { - return err + if errors.Is(err, badger.ErrTruncateNeeded) { + db, err = database.OpenTruncate(dbPath) + if err != nil { + return err + } + log.Warn().Msg("Open badger required truncate. Possible data loss.") + } else { + return err + } } defer func() { if err := db.Close(); err != nil { @@ -229,7 +238,8 @@ func main() { ) // Write cert that proxy uses - err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) + certPath := filepath.Join(opt.RootDirectory, "insecure-cert.pem") + err = ioutil.WriteFile(filepath.Join(opt.RootDirectory, "insecure-cert.pem"), []byte(insecure.ServerCert), os.ModePerm) if err != nil { return errors.Wrap(err, "write server cert") } diff --git a/cmd/package/package.go b/cmd/package/package.go index b2521f2d78..8060c42a29 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -129,8 +129,10 @@ func main() { return packaging.BuildDeb(opt) case "rpm": return packaging.BuildRPM(opt) + case "msi": + return packaging.BuildMSI(opt) default: - return errors.New("type must be one of ('pkg', 'deb', 'rpm')") + return errors.New("type must be one of ('pkg', 'deb', 'rpm', 'msi')") } } diff --git a/pkg/database/database.go b/pkg/database/database.go index 100377348d..ac3481b54b 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -22,7 +22,7 @@ type BadgerDB struct { closeChan chan struct{} } -// Open opens (initializing if necessary) a new Badger database at the specified +// Open opens (initializing if necessary) a Badger database at the specified // path. Users must close the DB with Close(). func Open(path string) (*BadgerDB, error) { // DefaultOptions sets synchronous writes to true (maximum data integrity). @@ -38,6 +38,26 @@ func Open(path string) (*BadgerDB, error) { return b, nil } +// OpenTruncate opens (initializing and/or truncating if necessary) a Badger +// database at the specified path. Users must close the DB with Close(). +// +// Prefer Open in the general case, but after a bad shutdown it may be necessary +// to call OpenTruncate. This may cause data loss. Detect this situation by +// looking for badger.ErrTruncateNeeded. +func OpenTruncate(path string) (*BadgerDB, error) { + // DefaultOptions sets synchronous writes to true (maximum data integrity). + // TODO implement logging? + db, err := badger.Open(badger.DefaultOptions(path).WithLogger(nil).WithTruncate(true)) + if err != nil { + return nil, errors.Wrapf(err, "open badger with truncate %s", path) + } + + b := &BadgerDB{DB: db} + b.startBackgroundCompaction() + + return b, nil +} + // startBackgroundCompaction starts a background loop that will call the // compaction method on the database. Badger does not do this automatically, so // we need to be sure to do so here (or elsewhere). diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 96eb12a5b7..ea8871a7b9 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -156,20 +156,6 @@ func writeScripts(opt Options, rootPath string) error { return nil } -func writeSecret(opt Options, orbitRoot string) error { - // Enroll secret - path := filepath.Join(orbitRoot, "secret") - if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "mkdir") - } - - if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - func writeLaunchd(opt Options, rootPath string) error { // launchd is the service mechanism on macOS path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist") diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index a0420cb171..e315f297c8 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -71,7 +71,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{ .FleetURL }}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} - {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} + {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret.txt{{ end }} {{ if .Debug }}ORBIT_DEBUGtrue{{ end }} KeepAlive diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index a12ef7954e..f3f2c518ce 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -3,9 +3,11 @@ package packaging import ( "io" + "io/ioutil" "os" "path/filepath" + "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" @@ -98,3 +100,17 @@ func initializeUpdates(updateOpt update.Options) error { return nil } + +// writeSecret writes the enroll secret to a text file +func writeSecret(opt Options, orbitRoot string) error { + path := filepath.Join(orbitRoot, "secret.txt") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/windows.go b/pkg/packaging/windows.go new file mode 100644 index 0000000000..cad1f53ee8 --- /dev/null +++ b/pkg/packaging/windows.go @@ -0,0 +1,104 @@ +package packaging + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/packaging/wix" + "github.com/fleetdm/orbit/pkg/update" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +// BuildMSI builds a Windows .msi. +func BuildMSI(opt Options) error { + // Initialize directories + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "root") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create root dir") + } + orbitRoot := filesystemRoot + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + // Initialize autoupdate metadata + + updateOpt := update.DefaultOptions + updateOpt.Platform = "windows" + updateOpt.RootDirectory = orbitRoot + updateOpt.OrbitChannel = opt.OrbitChannel + updateOpt.OsquerydChannel = opt.OsquerydChannel + updateOpt.ServerURL = opt.UpdateURL + if opt.UpdateRoots != "" { + updateOpt.RootKeys = opt.UpdateRoots + } + + if err := initializeUpdates(updateOpt); err != nil { + return errors.Wrap(err, "initialize updates") + } + + // Write files + + if err := writeSecret(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write enroll secret") + } + + if err := writeWixFile(opt, tmpDir); err != nil { + return errors.Wrap(err, "write wix file") + } + + if err := wix.Heat(tmpDir); err != nil { + return errors.Wrap(err, "package root files") + } + + if err := wix.TransformHeat(filepath.Join(tmpDir, "heat.wxs")); err != nil { + return errors.Wrap(err, "transform heat") + } + + if err := wix.Candle(tmpDir); err != nil { + return errors.Wrap(err, "build package") + } + + if err := wix.Light(tmpDir); err != nil { + return errors.Wrap(err, "build package") + } + + filename := fmt.Sprintf("orbit-osquery_%s.msi", opt.Version) + if err := os.Rename(filepath.Join(tmpDir, "orbit.msi"), filename); err != nil { + return errors.Wrap(err, "rename msi") + } + log.Info().Str("path", filename).Msg("wrote msi package") + + return nil +} + +func writeWixFile(opt Options, rootPath string) error { + // PackageInfo is metadata for the pkg + path := filepath.Join(rootPath, "main.wxs") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := windowsWixTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), 0o666); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/windows_templates.go b/pkg/packaging/windows_templates.go new file mode 100644 index 0000000000..6558200144 --- /dev/null +++ b/pkg/packaging/windows_templates.go @@ -0,0 +1,78 @@ +package packaging + +import "text/template" + +// Partially adapted from Launcher's wix XML in +// https://github.com/kolide/launcher/blob/master/pkg/packagekit/internal/assets/main.wxs. +var windowsWixTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`)) diff --git a/pkg/packaging/wix/transform.go b/pkg/packaging/wix/transform.go new file mode 100644 index 0000000000..e95a935efd --- /dev/null +++ b/pkg/packaging/wix/transform.go @@ -0,0 +1,113 @@ +package wix + +import ( + "bytes" + "encoding/xml" + "io/ioutil" + + "github.com/pkg/errors" +) + +type node struct { + XMLName xml.Name + Attrs attrs `xml:",any,attr"` + Content string `xml:",chardata"` + Children []*node `xml:",any"` +} + +type attrs []*xml.Attr + +// Get the value of the attr with the provided name, otherwise returning an +// empty string. +func (a attrs) Get(name string) string { + for _, attr := range a { + if attr.Name.Local == name { + return attr.Value + } + } + + return "" +} + +func xmlAttr(name, value string) *xml.Attr { + return &xml.Attr{Name: xml.Name{Local: name}, Value: value} +} + +func xmlNode(name string, attrs ...*xml.Attr) *node { + return &node{ + XMLName: xml.Name{Local: name}, + Attrs: attrs, + } +} + +func TransformHeat(path string) error { + contents, err := ioutil.ReadFile(path) + if err != nil { + return errors.Wrap(err, "read file") + } + + // Eliminate line feeds (they cause extra junk in the result) + contents = bytes.ReplaceAll(contents, []byte("\r"), []byte("")) + + var n node + if err := xml.Unmarshal(contents, &n); err != nil { + return errors.Wrap(err, "unmarshal xml") + } + + stack := []*node{} + if err := transform(&n, &stack); err != nil { + return errors.Wrap(err, "in transform") + } + + contents, err = xml.MarshalIndent(n, "", " ") + if err != nil { + return errors.Wrap(err, "marshal xml") + } + + if err := ioutil.WriteFile(path, contents, 0o600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +func transform(cur *node, stack *[]*node) error { + // Clear namespace on all elements (generates unnecessarily noisy output if + // this is not done). + cur.XMLName.Space = "" + + // Change permissions for all files + if cur.XMLName.Local == "File" { + // This SDDL copied directly from osqueryd.exe after a regular + // osquery MSI install. We assume that osquery is getting the + // permissions correct and use exactly the same for our files. + // Using this cryptic string seems to be the only way to disable + // permission inheritance in a WiX package, so we may not have + // any option for something more readable. + sddl := "O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" + if cur.Attrs.Get("Name") == "secret.txt" { + // This SDDL copied from properly configured file on a Windows + // 10 machine. Permissions are same as below but with read + // access removed for regular users. + sddl = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)" + + } + cur.Children = append(cur.Children, xmlNode( + "PermissionEx", + xmlAttr("Sddl", sddl), + )) + } + + // push current node onto stack + *stack = append(*stack, cur) + // Recursively walk the children + for _, child := range cur.Children { + if err := transform(child, stack); err != nil { + return err + } + } + // pop current node from stack + *stack = (*stack)[:len(*stack)-1] + + return nil +} diff --git a/pkg/packaging/wix/wix.go b/pkg/packaging/wix/wix.go new file mode 100644 index 0000000000..c068d9cbd1 --- /dev/null +++ b/pkg/packaging/wix/wix.go @@ -0,0 +1,88 @@ +// Package wix runs the WiX packaging tools via Docker. +// +// WiX's documentation is available at https://wixtoolset.org/. +package wix + +import ( + "os" + "os/exec" + + "github.com/pkg/errors" +) + +const ( + directoryReference = "ORBITROOT" +) + +// Heat runs the WiX Heat command on the provided directory. +// +// The Heat command creates XML fragments allowing WiX to include the entire +// directory. See +// https://wixtoolset.org/documentation/manual/v3/overview/heat.html. +func Heat(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "heat", "dir", "root", // command in image + "-out", "heat.wxs", + "-gg", "-g1", // generate UUIDs (required by wix) + "-cg", "OrbitFiles", // set ComponentGroup name + "-scom", "-sfrag", "-srd", "-sreg", // suppress unneccesary generated items + "-dr", directoryReference, // set reference name + "-ke", // keep empty directories + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "heat failed") + } + + return nil +} + +// Candle runs the WiX Candle command on the provided directory. +// +// See +// https://wixtoolset.org/documentation/manual/v3/overview/candle.html. +func Candle(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "candle", "heat.wxs", "main.wxs", // command in image + "-ext", "WixUtilExtension", + "-arch", "x64", + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "candle failed") + } + + return nil +} + +// Light runs the WiX Light command on the provided directory. +// +// See +// https://wixtoolset.org/documentation/manual/v3/overview/light.html. +func Light(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "light", "heat.wixobj", "main.wixobj", // command in image + "-ext", "WixUtilExtension", + "-b", "root", // Set directory for finding heat files + "-out", "orbit.msi", + "-sval", // skip validation (otherwise Wine crashes) + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "light failed") + } + + return nil +} From 3d1cf985a78df3191ae1dc6d1dfcbfab56028d53 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 16 Apr 2021 17:24:11 -0700 Subject: [PATCH 092/115] Revert "Initial Windows support (#10)" (#11) This reverts commit 7767da94e87c7559b03eeb41a04218fd46f34468. This was accidentally force-pushed before merging and included the incorrect changes. --- cmd/orbit/orbit.go | 18 +---- cmd/package/package.go | 4 +- pkg/database/database.go | 22 +----- pkg/packaging/macos.go | 14 ++++ pkg/packaging/macos_templates.go | 2 +- pkg/packaging/packaging.go | 16 ---- pkg/packaging/windows.go | 104 -------------------------- pkg/packaging/windows_templates.go | 78 -------------------- pkg/packaging/wix/transform.go | 113 ----------------------------- pkg/packaging/wix/wix.go | 88 ---------------------- 10 files changed, 21 insertions(+), 438 deletions(-) delete mode 100644 pkg/packaging/windows.go delete mode 100644 pkg/packaging/windows_templates.go delete mode 100644 pkg/packaging/wix/transform.go delete mode 100644 pkg/packaging/wix/wix.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 0106eecf73..649cde203a 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/dgraph-io/badger/v2" "github.com/fleetdm/orbit/pkg/certificate" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" @@ -27,6 +26,7 @@ import ( ) const ( + certPath = "/tmp/fleet.pem" defaultRootDir = "/var/lib/orbit" ) @@ -143,18 +143,9 @@ func main() { return errors.Wrap(err, "initialize root dir") } - dbPath := filepath.Join(c.String("root-dir"), "orbit.db") - db, err := database.Open(dbPath) + db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) if err != nil { - if errors.Is(err, badger.ErrTruncateNeeded) { - db, err = database.OpenTruncate(dbPath) - if err != nil { - return err - } - log.Warn().Msg("Open badger required truncate. Possible data loss.") - } else { - return err - } + return err } defer func() { if err := db.Close(); err != nil { @@ -238,8 +229,7 @@ func main() { ) // Write cert that proxy uses - certPath := filepath.Join(opt.RootDirectory, "insecure-cert.pem") - err = ioutil.WriteFile(filepath.Join(opt.RootDirectory, "insecure-cert.pem"), []byte(insecure.ServerCert), os.ModePerm) + err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) if err != nil { return errors.Wrap(err, "write server cert") } diff --git a/cmd/package/package.go b/cmd/package/package.go index 8060c42a29..b2521f2d78 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -129,10 +129,8 @@ func main() { return packaging.BuildDeb(opt) case "rpm": return packaging.BuildRPM(opt) - case "msi": - return packaging.BuildMSI(opt) default: - return errors.New("type must be one of ('pkg', 'deb', 'rpm', 'msi')") + return errors.New("type must be one of ('pkg', 'deb', 'rpm')") } } diff --git a/pkg/database/database.go b/pkg/database/database.go index ac3481b54b..100377348d 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -22,7 +22,7 @@ type BadgerDB struct { closeChan chan struct{} } -// Open opens (initializing if necessary) a Badger database at the specified +// Open opens (initializing if necessary) a new Badger database at the specified // path. Users must close the DB with Close(). func Open(path string) (*BadgerDB, error) { // DefaultOptions sets synchronous writes to true (maximum data integrity). @@ -38,26 +38,6 @@ func Open(path string) (*BadgerDB, error) { return b, nil } -// OpenTruncate opens (initializing and/or truncating if necessary) a Badger -// database at the specified path. Users must close the DB with Close(). -// -// Prefer Open in the general case, but after a bad shutdown it may be necessary -// to call OpenTruncate. This may cause data loss. Detect this situation by -// looking for badger.ErrTruncateNeeded. -func OpenTruncate(path string) (*BadgerDB, error) { - // DefaultOptions sets synchronous writes to true (maximum data integrity). - // TODO implement logging? - db, err := badger.Open(badger.DefaultOptions(path).WithLogger(nil).WithTruncate(true)) - if err != nil { - return nil, errors.Wrapf(err, "open badger with truncate %s", path) - } - - b := &BadgerDB{DB: db} - b.startBackgroundCompaction() - - return b, nil -} - // startBackgroundCompaction starts a background loop that will call the // compaction method on the database. Badger does not do this automatically, so // we need to be sure to do so here (or elsewhere). diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index ea8871a7b9..96eb12a5b7 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -156,6 +156,20 @@ func writeScripts(opt Options, rootPath string) error { return nil } +func writeSecret(opt Options, orbitRoot string) error { + // Enroll secret + path := filepath.Join(orbitRoot, "secret") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + func writeLaunchd(opt Options, rootPath string) error { // launchd is the service mechanism on macOS path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist") diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index e315f297c8..a0420cb171 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -71,7 +71,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{ .FleetURL }}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} - {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret.txt{{ end }} + {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} {{ if .Debug }}ORBIT_DEBUGtrue{{ end }} KeepAlive diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index f3f2c518ce..a12ef7954e 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -3,11 +3,9 @@ package packaging import ( "io" - "io/ioutil" "os" "path/filepath" - "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" @@ -100,17 +98,3 @@ func initializeUpdates(updateOpt update.Options) error { return nil } - -// writeSecret writes the enroll secret to a text file -func writeSecret(opt Options, orbitRoot string) error { - path := filepath.Join(orbitRoot, "secret.txt") - if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "mkdir") - } - - if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} diff --git a/pkg/packaging/windows.go b/pkg/packaging/windows.go deleted file mode 100644 index cad1f53ee8..0000000000 --- a/pkg/packaging/windows.go +++ /dev/null @@ -1,104 +0,0 @@ -package packaging - -import ( - "bytes" - "fmt" - "io/ioutil" - "os" - "path/filepath" - - "github.com/fleetdm/orbit/pkg/constant" - "github.com/fleetdm/orbit/pkg/packaging/wix" - "github.com/fleetdm/orbit/pkg/update" - "github.com/pkg/errors" - "github.com/rs/zerolog/log" -) - -// BuildMSI builds a Windows .msi. -func BuildMSI(opt Options) error { - // Initialize directories - tmpDir, err := ioutil.TempDir("", "orbit-package") - if err != nil { - return errors.Wrap(err, "failed to create temp dir") - } - defer os.RemoveAll(tmpDir) - log.Debug().Str("path", tmpDir).Msg("created temp dir") - - filesystemRoot := filepath.Join(tmpDir, "root") - if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create root dir") - } - orbitRoot := filesystemRoot - if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "create orbit dir") - } - - // Initialize autoupdate metadata - - updateOpt := update.DefaultOptions - updateOpt.Platform = "windows" - updateOpt.RootDirectory = orbitRoot - updateOpt.OrbitChannel = opt.OrbitChannel - updateOpt.OsquerydChannel = opt.OsquerydChannel - updateOpt.ServerURL = opt.UpdateURL - if opt.UpdateRoots != "" { - updateOpt.RootKeys = opt.UpdateRoots - } - - if err := initializeUpdates(updateOpt); err != nil { - return errors.Wrap(err, "initialize updates") - } - - // Write files - - if err := writeSecret(opt, orbitRoot); err != nil { - return errors.Wrap(err, "write enroll secret") - } - - if err := writeWixFile(opt, tmpDir); err != nil { - return errors.Wrap(err, "write wix file") - } - - if err := wix.Heat(tmpDir); err != nil { - return errors.Wrap(err, "package root files") - } - - if err := wix.TransformHeat(filepath.Join(tmpDir, "heat.wxs")); err != nil { - return errors.Wrap(err, "transform heat") - } - - if err := wix.Candle(tmpDir); err != nil { - return errors.Wrap(err, "build package") - } - - if err := wix.Light(tmpDir); err != nil { - return errors.Wrap(err, "build package") - } - - filename := fmt.Sprintf("orbit-osquery_%s.msi", opt.Version) - if err := os.Rename(filepath.Join(tmpDir, "orbit.msi"), filename); err != nil { - return errors.Wrap(err, "rename msi") - } - log.Info().Str("path", filename).Msg("wrote msi package") - - return nil -} - -func writeWixFile(opt Options, rootPath string) error { - // PackageInfo is metadata for the pkg - path := filepath.Join(rootPath, "main.wxs") - if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "mkdir") - } - - var contents bytes.Buffer - if err := windowsWixTemplate.Execute(&contents, opt); err != nil { - return errors.Wrap(err, "execute template") - } - - if err := ioutil.WriteFile(path, contents.Bytes(), 0o666); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} diff --git a/pkg/packaging/windows_templates.go b/pkg/packaging/windows_templates.go deleted file mode 100644 index 6558200144..0000000000 --- a/pkg/packaging/windows_templates.go +++ /dev/null @@ -1,78 +0,0 @@ -package packaging - -import "text/template" - -// Partially adapted from Launcher's wix XML in -// https://github.com/kolide/launcher/blob/master/pkg/packagekit/internal/assets/main.wxs. -var windowsWixTemplate = template.Must(template.New("").Option("missingkey=error").Parse( - ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`)) diff --git a/pkg/packaging/wix/transform.go b/pkg/packaging/wix/transform.go deleted file mode 100644 index e95a935efd..0000000000 --- a/pkg/packaging/wix/transform.go +++ /dev/null @@ -1,113 +0,0 @@ -package wix - -import ( - "bytes" - "encoding/xml" - "io/ioutil" - - "github.com/pkg/errors" -) - -type node struct { - XMLName xml.Name - Attrs attrs `xml:",any,attr"` - Content string `xml:",chardata"` - Children []*node `xml:",any"` -} - -type attrs []*xml.Attr - -// Get the value of the attr with the provided name, otherwise returning an -// empty string. -func (a attrs) Get(name string) string { - for _, attr := range a { - if attr.Name.Local == name { - return attr.Value - } - } - - return "" -} - -func xmlAttr(name, value string) *xml.Attr { - return &xml.Attr{Name: xml.Name{Local: name}, Value: value} -} - -func xmlNode(name string, attrs ...*xml.Attr) *node { - return &node{ - XMLName: xml.Name{Local: name}, - Attrs: attrs, - } -} - -func TransformHeat(path string) error { - contents, err := ioutil.ReadFile(path) - if err != nil { - return errors.Wrap(err, "read file") - } - - // Eliminate line feeds (they cause extra junk in the result) - contents = bytes.ReplaceAll(contents, []byte("\r"), []byte("")) - - var n node - if err := xml.Unmarshal(contents, &n); err != nil { - return errors.Wrap(err, "unmarshal xml") - } - - stack := []*node{} - if err := transform(&n, &stack); err != nil { - return errors.Wrap(err, "in transform") - } - - contents, err = xml.MarshalIndent(n, "", " ") - if err != nil { - return errors.Wrap(err, "marshal xml") - } - - if err := ioutil.WriteFile(path, contents, 0o600); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - -func transform(cur *node, stack *[]*node) error { - // Clear namespace on all elements (generates unnecessarily noisy output if - // this is not done). - cur.XMLName.Space = "" - - // Change permissions for all files - if cur.XMLName.Local == "File" { - // This SDDL copied directly from osqueryd.exe after a regular - // osquery MSI install. We assume that osquery is getting the - // permissions correct and use exactly the same for our files. - // Using this cryptic string seems to be the only way to disable - // permission inheritance in a WiX package, so we may not have - // any option for something more readable. - sddl := "O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" - if cur.Attrs.Get("Name") == "secret.txt" { - // This SDDL copied from properly configured file on a Windows - // 10 machine. Permissions are same as below but with read - // access removed for regular users. - sddl = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)" - - } - cur.Children = append(cur.Children, xmlNode( - "PermissionEx", - xmlAttr("Sddl", sddl), - )) - } - - // push current node onto stack - *stack = append(*stack, cur) - // Recursively walk the children - for _, child := range cur.Children { - if err := transform(child, stack); err != nil { - return err - } - } - // pop current node from stack - *stack = (*stack)[:len(*stack)-1] - - return nil -} diff --git a/pkg/packaging/wix/wix.go b/pkg/packaging/wix/wix.go deleted file mode 100644 index c068d9cbd1..0000000000 --- a/pkg/packaging/wix/wix.go +++ /dev/null @@ -1,88 +0,0 @@ -// Package wix runs the WiX packaging tools via Docker. -// -// WiX's documentation is available at https://wixtoolset.org/. -package wix - -import ( - "os" - "os/exec" - - "github.com/pkg/errors" -) - -const ( - directoryReference = "ORBITROOT" -) - -// Heat runs the WiX Heat command on the provided directory. -// -// The Heat command creates XML fragments allowing WiX to include the entire -// directory. See -// https://wixtoolset.org/documentation/manual/v3/overview/heat.html. -func Heat(path string) error { - cmd := exec.Command( - "docker", "run", "--rm", "--platform", "linux/386", - "--volume", path+":/wix", // mount volume - "dactiv/wix:latest", // image name - "heat", "dir", "root", // command in image - "-out", "heat.wxs", - "-gg", "-g1", // generate UUIDs (required by wix) - "-cg", "OrbitFiles", // set ComponentGroup name - "-scom", "-sfrag", "-srd", "-sreg", // suppress unneccesary generated items - "-dr", directoryReference, // set reference name - "-ke", // keep empty directories - ) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - - if err := cmd.Run(); err != nil { - return errors.Wrap(err, "heat failed") - } - - return nil -} - -// Candle runs the WiX Candle command on the provided directory. -// -// See -// https://wixtoolset.org/documentation/manual/v3/overview/candle.html. -func Candle(path string) error { - cmd := exec.Command( - "docker", "run", "--rm", "--platform", "linux/386", - "--volume", path+":/wix", // mount volume - "dactiv/wix:latest", // image name - "candle", "heat.wxs", "main.wxs", // command in image - "-ext", "WixUtilExtension", - "-arch", "x64", - ) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - - if err := cmd.Run(); err != nil { - return errors.Wrap(err, "candle failed") - } - - return nil -} - -// Light runs the WiX Light command on the provided directory. -// -// See -// https://wixtoolset.org/documentation/manual/v3/overview/light.html. -func Light(path string) error { - cmd := exec.Command( - "docker", "run", "--rm", "--platform", "linux/386", - "--volume", path+":/wix", // mount volume - "dactiv/wix:latest", // image name - "light", "heat.wixobj", "main.wixobj", // command in image - "-ext", "WixUtilExtension", - "-b", "root", // Set directory for finding heat files - "-out", "orbit.msi", - "-sval", // skip validation (otherwise Wine crashes) - ) - cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr - - if err := cmd.Run(); err != nil { - return errors.Wrap(err, "light failed") - } - - return nil -} From 593de6ce08ddbee6b1073e8e78ffa1245c4a60f1 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 16 Apr 2021 17:26:30 -0700 Subject: [PATCH 093/115] Initial Windows support (#12) This commit adds support for Orbit's update and osquery execution capabilities on Windows. Still to come is the packaging tooling for building MSIs on Windows. --- cmd/orbit/orbit.go | 7 +++-- go.mod | 2 ++ go.sum | 23 +++++++++++++++ pkg/constant/constant.go | 3 -- pkg/constant/constant_notwindows.go | 9 ++++++ pkg/constant/constant_windows.go | 29 +++++++++++++++++++ pkg/platform/platform_notwindows.go | 28 +++++++++++++++++++ pkg/platform/platform_windows.go | 43 +++++++++++++++++++++++++++++ pkg/update/options_notwindows.go | 23 +++++++++++++++ pkg/update/options_windows.go | 31 +++++++++++++++++++++ pkg/update/update.go | 25 ++++++----------- 11 files changed, 201 insertions(+), 22 deletions(-) create mode 100644 pkg/constant/constant_notwindows.go create mode 100644 pkg/platform/platform_notwindows.go create mode 100644 pkg/platform/platform_windows.go create mode 100644 pkg/update/options_notwindows.go create mode 100644 pkg/update/options_windows.go diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 649cde203a..f1146879e8 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -26,8 +26,7 @@ import ( ) const ( - certPath = "/tmp/fleet.pem" - defaultRootDir = "/var/lib/orbit" + certPath = "/tmp/fleet.pem" ) var ( @@ -54,7 +53,7 @@ func main() { &cli.StringFlag{ Name: "root-dir", Usage: "Root directory for Orbit state", - Value: defaultRootDir, + Value: update.DefaultOptions.RootDirectory, EnvVars: []string{"ORBIT_ROOT_DIR"}, }, &cli.BoolFlag{ @@ -228,6 +227,8 @@ func main() { }, ) + certPath := filepath.Join(os.TempDir(), "fleet.crt") + // Write cert that proxy uses err = ioutil.WriteFile(certPath, []byte(insecure.ServerCert), os.ModePerm) if err != nil { diff --git a/go.mod b/go.mod index 27bad1d963..df417fe636 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/dgraph-io/badger/v2 v2.2007.2 github.com/fatih/color v1.10.0 github.com/goreleaser/nfpm/v2 v2.2.2 + github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect github.com/kr/text v0.2.0 // indirect github.com/mitchellh/gon v0.2.3 github.com/oklog/run v1.1.0 @@ -15,4 +16,5 @@ require ( github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 github.com/urfave/cli/v2 v2.3.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect + golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect ) diff --git a/go.sum b/go.sum index 47e4368da6..8b6b9598ed 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,7 @@ github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQ github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -47,6 +48,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= @@ -54,6 +56,7 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/ashanbrown/forbidigo v1.0.0 h1:QdNXBduDUopc3GW+YVYZn8jzmIMklQiCfdN2N5+dQeE= github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyafc3ntEGh2BBAg= @@ -114,11 +117,13 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-critic/go-critic v0.5.2 h1:3RJdgf6u4NZUumoP8nzbqiiNT8e1tC2Oc7jlgqre/IA= github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= @@ -126,6 +131,7 @@ github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= @@ -148,6 +154,7 @@ github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUP github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= @@ -238,6 +245,7 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/goreleaser/chglog v0.1.2 h1:tdzAb/ILeMnphzI9zQ7Nkq+T8R9qyXli8GydD8plFRY= github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= @@ -290,6 +298,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= +github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -313,6 +323,7 @@ github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xl github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= @@ -402,6 +413,7 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= @@ -409,10 +421,12 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -471,6 +485,7 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= @@ -491,7 +506,9 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= @@ -582,6 +599,7 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -691,6 +709,7 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190529164535-6a60838ec259/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -714,7 +733,10 @@ golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -823,6 +845,7 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= diff --git a/pkg/constant/constant.go b/pkg/constant/constant.go index 8037198348..e95738b37a 100644 --- a/pkg/constant/constant.go +++ b/pkg/constant/constant.go @@ -5,9 +5,6 @@ const ( DefaultDirMode = 0o755 // DefaultFileMode is the default file mode to apply to created files. DefaultFileMode = 0o600 - // DefaultExecutableMode is the default file mode to apply to created - // executable files. - DefaultExecutableMode = 0o755 ) // ExecutableExtension returns the extension used for executables on the diff --git a/pkg/constant/constant_notwindows.go b/pkg/constant/constant_notwindows.go new file mode 100644 index 0000000000..6d00d67455 --- /dev/null +++ b/pkg/constant/constant_notwindows.go @@ -0,0 +1,9 @@ +//+build !windows + +package constant + +const ( + // DefaultExecutableMode is the default file mode to apply to created + // executable files. + DefaultExecutableMode = 0o755 +) diff --git a/pkg/constant/constant_windows.go b/pkg/constant/constant_windows.go index 2e444d9990..5e71091ae9 100644 --- a/pkg/constant/constant_windows.go +++ b/pkg/constant/constant_windows.go @@ -1,5 +1,34 @@ +//+build windows + package constant +import ( + "github.com/pkg/errors" + "golang.org/x/sys/windows" +) + const ( PlatformName = "windows" + // DefaultExecutableMode is the default file mode to apply to created + // executable files. For Windows this doesn't do anything besides setting + // read-only. See https://golang.org/pkg/os/#Chmod. + DefaultExecutableMode = 0o700 ) + +var ( + // These identifiers can be found in + // https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/security-identifiers-in-windows + // and are used in the same fashion as in osquery. See + // https://github.com/osquery/osquery/blob/d2be385d71f401c85872f00d479df8f499164c5a/tools/deployment/chocolatey/tools/osquery_utils.ps1. + SystemSID = mustSID("S-1-5-18") + AdminSID = mustSID("S-1-5-32-544") + UserSID = mustSID("S-1-5-32-545") +) + +func mustSID(identifier string) *windows.SID { + sid, err := windows.StringToSid(identifier) + if err != nil { + panic(errors.Wrap(err, "create sid")) + } + return sid +} diff --git a/pkg/platform/platform_notwindows.go b/pkg/platform/platform_notwindows.go new file mode 100644 index 0000000000..18f05c2b8f --- /dev/null +++ b/pkg/platform/platform_notwindows.go @@ -0,0 +1,28 @@ +//+build !windows + +package platform + +import ( + "os" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/pkg/errors" +) + +// ChmodExecutableDirectory sets the appropriate permissions on an executable +// file. On POSIX this is a normal chmod call. +func ChmodExecutableDirectory(path string) error { + if err := os.Chmod(path, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "chmod executable directory") + } + return nil +} + +// ChmodExecutable sets the appropriate permissions on the parent directory of +// an executable file. On POSIX this is a regular chmod call. +func ChmodExecutable(path string) error { + if err := os.Chmod(path, constant.DefaultExecutableMode); err != nil { + return errors.Wrap(err, "chmod executable") + } + return nil +} diff --git a/pkg/platform/platform_windows.go b/pkg/platform/platform_windows.go new file mode 100644 index 0000000000..7425427eec --- /dev/null +++ b/pkg/platform/platform_windows.go @@ -0,0 +1,43 @@ +//+build windows + +package platform + +import ( + "github.com/fleetdm/orbit/pkg/constant" + "github.com/pkg/errors" + + "github.com/hectane/go-acl" +) + +// ChmodExecutableDirectory sets the appropriate permissions on the parent +// directory of an executable file. On Windows this involves setting the +// appropriate ACLs. +func ChmodExecutableDirectory(path string) error { + if err := acl.Chmod(path, constant.DefaultExecutableMode); err != nil { + return errors.Wrap(err, "chmod path") + } + + const fullControl = uint32(2032127) + const readAndExecute = uint32(131241) + if err := acl.Apply( + path, + true, + false, + acl.GrantSid(fullControl, constant.SystemSID), + acl.GrantSid(fullControl, constant.AdminSID), + acl.GrantSid(readAndExecute, constant.UserSID), + ); err != nil { + return errors.Wrap(err, "apply ACLs") + } + + return nil +} + +// ChmodExecutable sets the appropriate permissions on an executable file. On +// Windows this involves setting the appropriate ACLs. +func ChmodExecutable(path string) error { + if err := acl.Chmod(path, constant.DefaultExecutableMode); err != nil { + return errors.Wrap(err, "apply ACLs") + } + return nil +} diff --git a/pkg/update/options_notwindows.go b/pkg/update/options_notwindows.go new file mode 100644 index 0000000000..11ba2cfcd0 --- /dev/null +++ b/pkg/update/options_notwindows.go @@ -0,0 +1,23 @@ +// +build !windows + +package update + +import ( + "github.com/fleetdm/orbit/pkg/constant" + "github.com/theupdateframework/go-tuf/client" +) + +var ( + // DefaultOptions are the default options to use when creating an update + // client. + DefaultOptions = Options{ + RootDirectory: "/var/lib/orbit", + ServerURL: defaultURL, + RootKeys: defaultRootKeys, + LocalStore: client.MemoryLocalStore(), + InsecureTransport: false, + Platform: constant.PlatformName, + OrbitChannel: "stable", + OsquerydChannel: "stable", + } +) diff --git a/pkg/update/options_windows.go b/pkg/update/options_windows.go new file mode 100644 index 0000000000..956ffaf72f --- /dev/null +++ b/pkg/update/options_windows.go @@ -0,0 +1,31 @@ +package update + +import ( + "os" + "path/filepath" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/theupdateframework/go-tuf/client" +) + +var ( + // DefaultOptions are the default options to use when creating an update + // client. + DefaultOptions = Options{ + RootDirectory: `C:\Program Files\Orbit`, + ServerURL: defaultURL, + RootKeys: defaultRootKeys, + LocalStore: client.MemoryLocalStore(), + InsecureTransport: false, + Platform: constant.PlatformName, + OrbitChannel: "stable", + OsquerydChannel: "stable", + } +) + +func init() { + // Set root directory to value of ProgramFiles environment variable if not set + if dir := os.Getenv("ProgramFiles"); dir != "" { + DefaultOptions.RootDirectory = filepath.Join(dir, "Orbit") + } +} diff --git a/pkg/update/update.go b/pkg/update/update.go index 3178aa5ddc..cde994c006 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -11,6 +11,7 @@ import ( "path/filepath" "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/platform" "github.com/pkg/errors" "github.com/rs/zerolog/log" "github.com/theupdateframework/go-tuf/client" @@ -53,21 +54,6 @@ type Options struct { OsquerydChannel string } -var ( - // DefaultOptions are the default options to use when creating an update - // client. - DefaultOptions = Options{ - RootDirectory: "/var/lib/orbit", - ServerURL: defaultURL, - RootKeys: defaultRootKeys, - LocalStore: client.MemoryLocalStore(), - InsecureTransport: false, - Platform: constant.PlatformName, - OrbitChannel: "stable", - OsquerydChannel: "stable", - } -) - // New creates a new updater given the provided options. All the necessary // directories are initialized. func New(opt Options) (*Updater, error) { @@ -196,12 +182,19 @@ func (u *Updater) Download(repoPath, localPath string) error { return errors.Wrap(err, "initialize download dir") } + // Additional chmod only necessary on Windows, effectively a no-op on other + // platforms. + if err := platform.ChmodExecutableDirectory(filepath.Dir(localPath)); err != nil { + return err + } + // The go-tuf client handles checking of max size and hash. if err := u.client.Download(repoPath, &fileDestination{tmp}); err != nil { return errors.Wrapf(err, "download target %s", repoPath) } + tmp.Close() - if err := os.Chmod(tmp.Name(), constant.DefaultExecutableMode); err != nil { + if err := platform.ChmodExecutable(tmp.Name()); err != nil { return errors.Wrap(err, "chmod download") } From 9a4de647ce1167da43c9224006bb92fe4b7a41ac Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Sat, 17 Apr 2021 11:52:37 -0700 Subject: [PATCH 094/115] Add support for Windows MSI packaging (#13) - Support building Windows MSIs. - Refactor some of the general update/packaging code. - Update documentation. Windows codesigning support still to come. --- README.md | 8 +- cmd/orbit/orbit.go | 45 +++++++++--- cmd/package/package.go | 4 +- pkg/packaging/macos.go | 14 ---- pkg/packaging/macos_templates.go | 2 +- pkg/packaging/packaging.go | 16 ++++ pkg/packaging/windows.go | 104 ++++++++++++++++++++++++++ pkg/packaging/windows_templates.go | 87 ++++++++++++++++++++++ pkg/packaging/wix/transform.go | 113 +++++++++++++++++++++++++++++ pkg/packaging/wix/wix.go | 88 ++++++++++++++++++++++ pkg/platform/platform_windows.go | 21 ++++-- pkg/update/hash.go | 1 + pkg/update/runner.go | 17 ++--- pkg/update/update.go | 48 ++++++++++-- 14 files changed, 518 insertions(+), 50 deletions(-) create mode 100644 pkg/packaging/windows.go create mode 100644 pkg/packaging/windows_templates.go create mode 100644 pkg/packaging/wix/transform.go create mode 100644 pkg/packaging/wix/wix.go diff --git a/README.md b/README.md index df9e5d1953..72fa217b81 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ To report a bug or request a feature, [click here](https://github.com/fleetdm/fl | Package tooling for macOS `.pkg` | ✅ | | Package tooling for Linux `.deb` | ✅ | | Package tooling for Linux `.rpm` | ✅ | -| Package tooling for Windows `.msi` | 🔜 | +| Package tooling for Windows `.msi` | ✅ | | Manage/update osquery extensions | 🔜 | | Manage cgroups for Linux performance | 🔜 | @@ -103,7 +103,7 @@ Orbit, like standalone osquery, is typically deployed via OS-specific packages. - **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. -- **Windows** (coming soon) - `.msi` package generation - Persistence via Services. +- **Windows** - `.msi` package generation - Persistence via Services. ### Building packages @@ -159,6 +159,10 @@ This process may take several minutes to complete as the Notarization process co After successful notarization, the generated "ticket" is automatically stapled to the package. +#### Windows packaging + +Windows packaging utilizes Docker containers to run the WiX packaging tools. This should enable building Windows packages from any operating system that supports Docker. Please file an issue for any packaging-related issues. + ## FAQs ### How does Orbit compare with Kolide Launcher? diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index f1146879e8..8ff79f8aa0 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -4,6 +4,7 @@ import ( "context" "crypto/x509" "fmt" + "io/fs" "io/ioutil" "net/url" "os" @@ -25,10 +26,6 @@ import ( "github.com/urfave/cli/v2" ) -const ( - certPath = "/tmp/fleet.pem" -) - var ( // Flags set by goreleaser during build version = "" @@ -37,11 +34,6 @@ var ( ) func main() { - log.Logger = log.Output( - zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano}, - ) - zerolog.SetGlobalLevel(zerolog.InfoLevel) - app := cli.NewApp() app.Name = "Orbit osquery" app.Usage = "A powered-up, (near) drop-in replacement for osquery" @@ -108,6 +100,10 @@ func main() { Name: "version", Usage: "Get Orbit version", }, + &cli.StringFlag{ + Name: "log-file", + Usage: "Log to this file path in addition to stderr", + }, } app.Action = func(c *cli.Context) error { if c.Bool("version") { @@ -115,6 +111,19 @@ func main() { return nil } + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano, NoColor: true}) + if logfile := c.String("log-file"); logfile != "" { + f, err := os.OpenFile(logfile, os.O_CREATE|os.O_APPEND, 0o600) + if err != nil { + return errors.Wrap(err, "open logfile") + } + log.Logger = log.Output(zerolog.MultiLevelWriter( + zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339Nano, NoColor: true}, + zerolog.ConsoleWriter{Out: f, TimeFormat: time.RFC3339Nano, NoColor: true}, + )) + } + zerolog.SetGlobalLevel(zerolog.InfoLevel) + if c.Bool("debug") { zerolog.SetGlobalLevel(zerolog.DebugLevel) } @@ -175,6 +184,24 @@ func main() { return err } + // Clear leftover files from updates + if err := filepath.Walk(c.String("root-dir"), func(path string, info fs.FileInfo, err error) error { + // Ignore anything not containing .old extension + if !strings.HasSuffix(path, ".old") { + return nil + } + + if err := os.RemoveAll(path); err != nil { + log.Info().Err(err).Msg("failed to remove .old") + return nil + } + log.Debug().Str("path", path).Msg("cleaned up old") + + return nil + }); err != nil { + return errors.Wrap(err, "cleanup old files") + } + var g run.Group updateRunner, err := update.NewRunner(updater, update.RunnerOptions{ diff --git a/cmd/package/package.go b/cmd/package/package.go index b2521f2d78..8060c42a29 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -129,8 +129,10 @@ func main() { return packaging.BuildDeb(opt) case "rpm": return packaging.BuildRPM(opt) + case "msi": + return packaging.BuildMSI(opt) default: - return errors.New("type must be one of ('pkg', 'deb', 'rpm')") + return errors.New("type must be one of ('pkg', 'deb', 'rpm', 'msi')") } } diff --git a/pkg/packaging/macos.go b/pkg/packaging/macos.go index 96eb12a5b7..ea8871a7b9 100644 --- a/pkg/packaging/macos.go +++ b/pkg/packaging/macos.go @@ -156,20 +156,6 @@ func writeScripts(opt Options, rootPath string) error { return nil } -func writeSecret(opt Options, orbitRoot string) error { - // Enroll secret - path := filepath.Join(orbitRoot, "secret") - if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { - return errors.Wrap(err, "mkdir") - } - - if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { - return errors.Wrap(err, "write file") - } - - return nil -} - func writeLaunchd(opt Options, rootPath string) error { // launchd is the service mechanism on macOS path := filepath.Join(rootPath, "Library", "LaunchDaemons", "com.fleetdm.orbit.plist") diff --git a/pkg/packaging/macos_templates.go b/pkg/packaging/macos_templates.go index a0420cb171..e315f297c8 100644 --- a/pkg/packaging/macos_templates.go +++ b/pkg/packaging/macos_templates.go @@ -71,7 +71,7 @@ var macosLaunchdTemplate = template.Must(template.New("").Option("missingkey=err {{ if .Insecure }}ORBIT_INSECUREtrue{{ end }} {{ if .FleetURL }}ORBIT_FLEET_URL{{ .FleetURL }}{{ end }} {{ if .FleetCertificate }}ORBIT_FLEET_CERTIFICATE/var/lib/orbit/fleet.pem{{ end }} - {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret{{ end }} + {{ if .EnrollSecret }}ORBIT_ENROLL_SECRET_PATH/var/lib/orbit/secret.txt{{ end }} {{ if .Debug }}ORBIT_DEBUGtrue{{ end }} KeepAlive diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index a12ef7954e..9f6887d3c4 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -3,9 +3,11 @@ package packaging import ( "io" + "io/ioutil" "os" "path/filepath" + "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/update" "github.com/fleetdm/orbit/pkg/update/filestore" "github.com/pkg/errors" @@ -98,3 +100,17 @@ func initializeUpdates(updateOpt update.Options) error { return nil } + +func writeSecret(opt Options, orbitRoot string) error { + // Enroll secret + path := filepath.Join(orbitRoot, "secret.txt") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + if err := ioutil.WriteFile(path, []byte(opt.EnrollSecret), 0600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/windows.go b/pkg/packaging/windows.go new file mode 100644 index 0000000000..cad1f53ee8 --- /dev/null +++ b/pkg/packaging/windows.go @@ -0,0 +1,104 @@ +package packaging + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/fleetdm/orbit/pkg/constant" + "github.com/fleetdm/orbit/pkg/packaging/wix" + "github.com/fleetdm/orbit/pkg/update" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +// BuildMSI builds a Windows .msi. +func BuildMSI(opt Options) error { + // Initialize directories + tmpDir, err := ioutil.TempDir("", "orbit-package") + if err != nil { + return errors.Wrap(err, "failed to create temp dir") + } + defer os.RemoveAll(tmpDir) + log.Debug().Str("path", tmpDir).Msg("created temp dir") + + filesystemRoot := filepath.Join(tmpDir, "root") + if err := os.MkdirAll(filesystemRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create root dir") + } + orbitRoot := filesystemRoot + if err := os.MkdirAll(orbitRoot, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "create orbit dir") + } + + // Initialize autoupdate metadata + + updateOpt := update.DefaultOptions + updateOpt.Platform = "windows" + updateOpt.RootDirectory = orbitRoot + updateOpt.OrbitChannel = opt.OrbitChannel + updateOpt.OsquerydChannel = opt.OsquerydChannel + updateOpt.ServerURL = opt.UpdateURL + if opt.UpdateRoots != "" { + updateOpt.RootKeys = opt.UpdateRoots + } + + if err := initializeUpdates(updateOpt); err != nil { + return errors.Wrap(err, "initialize updates") + } + + // Write files + + if err := writeSecret(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write enroll secret") + } + + if err := writeWixFile(opt, tmpDir); err != nil { + return errors.Wrap(err, "write wix file") + } + + if err := wix.Heat(tmpDir); err != nil { + return errors.Wrap(err, "package root files") + } + + if err := wix.TransformHeat(filepath.Join(tmpDir, "heat.wxs")); err != nil { + return errors.Wrap(err, "transform heat") + } + + if err := wix.Candle(tmpDir); err != nil { + return errors.Wrap(err, "build package") + } + + if err := wix.Light(tmpDir); err != nil { + return errors.Wrap(err, "build package") + } + + filename := fmt.Sprintf("orbit-osquery_%s.msi", opt.Version) + if err := os.Rename(filepath.Join(tmpDir, "orbit.msi"), filename); err != nil { + return errors.Wrap(err, "rename msi") + } + log.Info().Str("path", filename).Msg("wrote msi package") + + return nil +} + +func writeWixFile(opt Options, rootPath string) error { + // PackageInfo is metadata for the pkg + path := filepath.Join(rootPath, "main.wxs") + if err := os.MkdirAll(filepath.Dir(path), constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "mkdir") + } + + var contents bytes.Buffer + if err := windowsWixTemplate.Execute(&contents, opt); err != nil { + return errors.Wrap(err, "execute template") + } + + if err := ioutil.WriteFile(path, contents.Bytes(), 0o666); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} diff --git a/pkg/packaging/windows_templates.go b/pkg/packaging/windows_templates.go new file mode 100644 index 0000000000..bc07500700 --- /dev/null +++ b/pkg/packaging/windows_templates.go @@ -0,0 +1,87 @@ +package packaging + +import "text/template" + +// Partially adapted from Launcher's wix XML in +// https://github.com/kolide/launcher/blob/master/pkg/packagekit/internal/assets/main.wxs. +var windowsWixTemplate = template.Must(template.New("").Option("missingkey=error").Parse( + ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`)) diff --git a/pkg/packaging/wix/transform.go b/pkg/packaging/wix/transform.go new file mode 100644 index 0000000000..e95a935efd --- /dev/null +++ b/pkg/packaging/wix/transform.go @@ -0,0 +1,113 @@ +package wix + +import ( + "bytes" + "encoding/xml" + "io/ioutil" + + "github.com/pkg/errors" +) + +type node struct { + XMLName xml.Name + Attrs attrs `xml:",any,attr"` + Content string `xml:",chardata"` + Children []*node `xml:",any"` +} + +type attrs []*xml.Attr + +// Get the value of the attr with the provided name, otherwise returning an +// empty string. +func (a attrs) Get(name string) string { + for _, attr := range a { + if attr.Name.Local == name { + return attr.Value + } + } + + return "" +} + +func xmlAttr(name, value string) *xml.Attr { + return &xml.Attr{Name: xml.Name{Local: name}, Value: value} +} + +func xmlNode(name string, attrs ...*xml.Attr) *node { + return &node{ + XMLName: xml.Name{Local: name}, + Attrs: attrs, + } +} + +func TransformHeat(path string) error { + contents, err := ioutil.ReadFile(path) + if err != nil { + return errors.Wrap(err, "read file") + } + + // Eliminate line feeds (they cause extra junk in the result) + contents = bytes.ReplaceAll(contents, []byte("\r"), []byte("")) + + var n node + if err := xml.Unmarshal(contents, &n); err != nil { + return errors.Wrap(err, "unmarshal xml") + } + + stack := []*node{} + if err := transform(&n, &stack); err != nil { + return errors.Wrap(err, "in transform") + } + + contents, err = xml.MarshalIndent(n, "", " ") + if err != nil { + return errors.Wrap(err, "marshal xml") + } + + if err := ioutil.WriteFile(path, contents, 0o600); err != nil { + return errors.Wrap(err, "write file") + } + + return nil +} + +func transform(cur *node, stack *[]*node) error { + // Clear namespace on all elements (generates unnecessarily noisy output if + // this is not done). + cur.XMLName.Space = "" + + // Change permissions for all files + if cur.XMLName.Local == "File" { + // This SDDL copied directly from osqueryd.exe after a regular + // osquery MSI install. We assume that osquery is getting the + // permissions correct and use exactly the same for our files. + // Using this cryptic string seems to be the only way to disable + // permission inheritance in a WiX package, so we may not have + // any option for something more readable. + sddl := "O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" + if cur.Attrs.Get("Name") == "secret.txt" { + // This SDDL copied from properly configured file on a Windows + // 10 machine. Permissions are same as below but with read + // access removed for regular users. + sddl = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)" + + } + cur.Children = append(cur.Children, xmlNode( + "PermissionEx", + xmlAttr("Sddl", sddl), + )) + } + + // push current node onto stack + *stack = append(*stack, cur) + // Recursively walk the children + for _, child := range cur.Children { + if err := transform(child, stack); err != nil { + return err + } + } + // pop current node from stack + *stack = (*stack)[:len(*stack)-1] + + return nil +} diff --git a/pkg/packaging/wix/wix.go b/pkg/packaging/wix/wix.go new file mode 100644 index 0000000000..c068d9cbd1 --- /dev/null +++ b/pkg/packaging/wix/wix.go @@ -0,0 +1,88 @@ +// Package wix runs the WiX packaging tools via Docker. +// +// WiX's documentation is available at https://wixtoolset.org/. +package wix + +import ( + "os" + "os/exec" + + "github.com/pkg/errors" +) + +const ( + directoryReference = "ORBITROOT" +) + +// Heat runs the WiX Heat command on the provided directory. +// +// The Heat command creates XML fragments allowing WiX to include the entire +// directory. See +// https://wixtoolset.org/documentation/manual/v3/overview/heat.html. +func Heat(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "heat", "dir", "root", // command in image + "-out", "heat.wxs", + "-gg", "-g1", // generate UUIDs (required by wix) + "-cg", "OrbitFiles", // set ComponentGroup name + "-scom", "-sfrag", "-srd", "-sreg", // suppress unneccesary generated items + "-dr", directoryReference, // set reference name + "-ke", // keep empty directories + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "heat failed") + } + + return nil +} + +// Candle runs the WiX Candle command on the provided directory. +// +// See +// https://wixtoolset.org/documentation/manual/v3/overview/candle.html. +func Candle(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "candle", "heat.wxs", "main.wxs", // command in image + "-ext", "WixUtilExtension", + "-arch", "x64", + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "candle failed") + } + + return nil +} + +// Light runs the WiX Light command on the provided directory. +// +// See +// https://wixtoolset.org/documentation/manual/v3/overview/light.html. +func Light(path string) error { + cmd := exec.Command( + "docker", "run", "--rm", "--platform", "linux/386", + "--volume", path+":/wix", // mount volume + "dactiv/wix:latest", // image name + "light", "heat.wixobj", "main.wixobj", // command in image + "-ext", "WixUtilExtension", + "-b", "root", // Set directory for finding heat files + "-out", "orbit.msi", + "-sval", // skip validation (otherwise Wine crashes) + ) + cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr + + if err := cmd.Run(); err != nil { + return errors.Wrap(err, "light failed") + } + + return nil +} diff --git a/pkg/platform/platform_windows.go b/pkg/platform/platform_windows.go index 7425427eec..875eab8b8e 100644 --- a/pkg/platform/platform_windows.go +++ b/pkg/platform/platform_windows.go @@ -9,16 +9,15 @@ import ( "github.com/hectane/go-acl" ) +const ( + fullControl = uint32(2032127) + readAndExecute = uint32(131241) +) + // ChmodExecutableDirectory sets the appropriate permissions on the parent // directory of an executable file. On Windows this involves setting the // appropriate ACLs. func ChmodExecutableDirectory(path string) error { - if err := acl.Chmod(path, constant.DefaultExecutableMode); err != nil { - return errors.Wrap(err, "chmod path") - } - - const fullControl = uint32(2032127) - const readAndExecute = uint32(131241) if err := acl.Apply( path, true, @@ -36,8 +35,16 @@ func ChmodExecutableDirectory(path string) error { // ChmodExecutable sets the appropriate permissions on an executable file. On // Windows this involves setting the appropriate ACLs. func ChmodExecutable(path string) error { - if err := acl.Chmod(path, constant.DefaultExecutableMode); err != nil { + if err := acl.Apply( + path, + true, + false, + acl.GrantSid(fullControl, constant.SystemSID), + acl.GrantSid(fullControl, constant.AdminSID), + acl.GrantSid(readAndExecute, constant.UserSID), + ); err != nil { return errors.Wrap(err, "apply ACLs") } + return nil } diff --git a/pkg/update/hash.go b/pkg/update/hash.go index ada9f040d2..d75e47e29b 100644 --- a/pkg/update/hash.go +++ b/pkg/update/hash.go @@ -24,6 +24,7 @@ func CheckFileHash(meta *data.TargetFileMeta, localPath string) error { if err != nil { return errors.Wrap(err, "open file for hash") } + defer f.Close() if _, err := io.Copy(hashFunc, f); err != nil { return errors.Wrap(err, "read file for hash") diff --git a/pkg/update/runner.go b/pkg/update/runner.go index ac90cc4bdd..15b9e8ee0d 100644 --- a/pkg/update/runner.go +++ b/pkg/update/runner.go @@ -130,21 +130,20 @@ func (r *Runner) updateTarget(target, channel string) error { return errors.Wrap(err, "get binary") } - // Replace file/link - currentPath := r.client.LocalPath(target, "current") - if err := os.Remove(currentPath); err != nil && !os.IsNotExist(err) { - return errors.Wrap(err, "remove old current") + if target != "orbit" { + return nil } - if err := os.MkdirAll(filepath.Dir(currentPath), 0755); err != nil { - return errors.Wrap(err, "mkdir for symlink") + // Symlink Orbit binary + linkPath := filepath.Join(r.client.opt.RootDirectory, "bin", "orbit", filepath.Base(path)) + // Rename the old file otherwise overwrite fails + if err := os.Rename(linkPath, linkPath+".old"); err != nil { + return errors.Wrap(err, "move old symlink current") } - if err := os.Symlink(path, currentPath); err != nil { + if err := os.Symlink(path, linkPath); err != nil { return errors.Wrap(err, "symlink current") } - // TODO signal a restart? - return nil } diff --git a/pkg/update/update.go b/pkg/update/update.go index cde994c006..4980aa687d 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -4,11 +4,12 @@ package update import ( "crypto/tls" "encoding/json" - "io/ioutil" "net/http" "os" + "os/exec" "path" "path/filepath" + "runtime" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/platform" @@ -19,7 +20,8 @@ import ( ) const ( - binDir = "bin" + binDir = "bin" + stagingDir = "staging" defaultURL = "https://tuf.fleetctl.com" defaultRootKeys = `[{"keytype":"ed25519","scheme":"ed25519","keyid_hash_algorithms":["sha256","sha512"],"keyval":{"public":"6d71d3beac3b830be929f2b10d513448d49ec6bb62a680176b89ffdfca180eb4"}}]` @@ -157,7 +159,7 @@ func (u *Updater) Get(target, channel string) (string, error) { } if err := CheckFileHash(meta, localPath); err != nil { - log.Debug().Err(err).Msg("will redownload") + log.Debug().Str("info", err.Error()).Msg("change detected") return localPath, u.Download(repoPath, localPath) } @@ -169,7 +171,23 @@ func (u *Updater) Get(target, channel string) (string, error) { // Download downloads the target to the provided path. The file is deleted and // an error is returned if the hash does not match. func (u *Updater) Download(repoPath, localPath string) error { - tmp, err := ioutil.TempFile("", "orbit-download") + staging := filepath.Join(u.opt.RootDirectory, stagingDir) + + if err := os.MkdirAll(staging, constant.DefaultDirMode); err != nil { + return errors.Wrap(err, "initialize download dir") + } + + // Additional chmod only necessary on Windows, effectively a no-op on other + // platforms. + if err := platform.ChmodExecutableDirectory(staging); err != nil { + return err + } + + tmp, err := os.OpenFile( + filepath.Join(staging, filepath.Base(localPath)), + os.O_CREATE|os.O_WRONLY, + constant.DefaultExecutableMode, + ) if err != nil { return errors.Wrap(err, "open temp file for download") } @@ -177,6 +195,9 @@ func (u *Updater) Download(repoPath, localPath string) error { tmp.Close() os.Remove(tmp.Name()) }() + if err := platform.ChmodExecutable(tmp.Name()); err != nil { + return errors.Wrap(err, "chmod download") + } if err := os.MkdirAll(filepath.Dir(localPath), constant.DefaultDirMode); err != nil { return errors.Wrap(err, "initialize download dir") @@ -192,10 +213,23 @@ func (u *Updater) Download(repoPath, localPath string) error { if err := u.client.Download(repoPath, &fileDestination{tmp}); err != nil { return errors.Wrapf(err, "download target %s", repoPath) } - tmp.Close() + if err := tmp.Close(); err != nil { + return errors.Wrap(err, "close tmp file") + } - if err := platform.ChmodExecutable(tmp.Name()); err != nil { - return errors.Wrap(err, "chmod download") + if runtime.GOOS == constant.PlatformName { + out, err := exec.Command(tmp.Name(), "--version").CombinedOutput() + if err != nil { + + return errors.Wrapf(err, "exec new version: %s", string(out)) + } + } + + if runtime.GOOS == "windows" { + // Remove old file first + if err := os.Rename(localPath, localPath+".old"); err != nil && !os.IsNotExist(err) { + return errors.Wrap(err, "rename old") + } } if err := os.Rename(tmp.Name(), localPath); err != nil { From 6e54f9ed8f9e7a187f27cd669c3d1ef58a5364f3 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Sat, 17 Apr 2021 11:55:35 -0700 Subject: [PATCH 095/115] Update version to 0.0.2 (#14) --- cmd/package/package.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/package/package.go b/cmd/package/package.go index 8060c42a29..f226d0767e 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -52,7 +52,7 @@ func main() { &cli.StringFlag{ Name: "version", Usage: "Version for package product", - Value: "0.0.1", + Value: "0.0.2", Destination: &opt.Version, }, &cli.BoolFlag{ From 5b0020fea44f80a618d23753a3d2a98e1de02d72 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Sat, 17 Apr 2021 11:58:08 -0700 Subject: [PATCH 096/115] Update go.sum (#15) --- go.sum | 204 --------------------------------------------------------- 1 file changed, 204 deletions(-) diff --git a/go.sum b/go.sum index 8b6b9598ed..7dc47ae791 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -13,34 +12,24 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Djarvur/go-err113 v0.1.0 h1:uCRZZOdMQ0TZPHYTdYpoC0bLYJKPEHPUJ8MeAa51lNU= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -48,7 +37,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= @@ -56,21 +44,15 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ashanbrown/forbidigo v1.0.0 h1:QdNXBduDUopc3GW+YVYZn8jzmIMklQiCfdN2N5+dQeE= github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyafc3ntEGh2BBAg= -github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a h1:/U9tbJzDRof4fOR51vwzWdIBsIH6R2yU0KG1MBRM2Js= github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= -github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= -github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -83,22 +65,13 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/daixiang0/gci v0.2.4/go.mod h1:+AV8KmHTGxxwp/pY84TLQfFKp2vuKXXJVzF3kD/hfR4= -github.com/daixiang0/gci v0.2.7 h1:bosLNficubzJZICsVzxuyNc6oAbdz0zcqLG2G/RxtY4= github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denis-tingajkin/go-header v0.3.1/go.mod h1:sq/2IxMhaZX+RRcgHfCRx/m0M5na0fBt4/CRe7Lrji0= -github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= @@ -110,30 +83,20 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-critic/go-critic v0.5.2 h1:3RJdgf6u4NZUumoP8nzbqiiNT8e1tC2Oc7jlgqre/IA= github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -143,29 +106,18 @@ github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dT github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -178,8 +130,6 @@ github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -190,36 +140,21 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= -github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= -github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= -github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d h1:pXTK/gkVNs7Zyy7WKgLXmpQ5bHTrq5GDsp8R9Qs67g0= github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.33.0/go.mod h1:zMnMLSCaDlrXExYsuq2LOweE9CHVqYk5jexk23UsjYM= -github.com/golangci/golangci-lint v1.34.1 h1:xf1yVlLBNeCIoOHWXhwqnUeaqzONllRSgiLSahNt0Mw= github.com/golangci/golangci-lint v1.34.1/go.mod h1:6Bnn7T0JYin7uukitgL6f9E9auQatlT0RMNOKG9lSHU= -github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= -github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= -github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 h1:XQKc8IYQOeRwVs36tDrEmTgDgP88d5iEURwpmtiAlOM= github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= -github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -230,58 +165,41 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= -github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688 h1:jyGRCFMyDK/gKe6QRZQWci5+wEUBFElvxLHs3iwO3hY= github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/goreleaser/chglog v0.1.2 h1:tdzAb/ILeMnphzI9zQ7Nkq+T8R9qyXli8GydD8plFRY= github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= -github.com/goreleaser/fileglob v0.3.1 h1:OTFDWqUUHjQazk2N5GdUqEbqT/grBnRARaAXsV07q1Y= github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= -github.com/goreleaser/nfpm v1.10.3 h1:NzpWKKzSFr7JOn55XN0SskyFOjP6BkvRt3JujoX8fws= -github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk= -github.com/goreleaser/nfpm/v2 v2.2.2 h1:aLGEqhMDcSNg1RHwzUBHwRUbmiK8HfD1sTq8bG7/WMc= github.com/goreleaser/nfpm/v2 v2.2.2/go.mod h1:WtPzYQh+Ls57prS9RzXegrGejqILUS1aZibXHTTJ8eI= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= -github.com/gostaticanalysis/analysisutil v0.6.1 h1:/1JkoHe4DVxur+0wPvi26FoQfe1E3ZGqIXS3aaSLiaw= github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= -github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2 h1:STV8OvzphW1vlhPFxcG8d6OIilzBSKRAoWFJt+Onu10= github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.6.3 h1:tuulM+WnToeqa05z83YLmKabZxrySOmJAd4mJ+s2Nfg= github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -291,46 +209,34 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg= github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -340,112 +246,81 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk= github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= -github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= -github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e h1:2U5rOmpaB96l35w+NDjMtmmrp2e6a6AJKoc4B5+7UwA= github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mbilski/exhaustivestruct v1.1.0 h1:4ykwscnAFeHJruT+EY3M3vdeP8uXMh0VV2E61iR7XD8= github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo= github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= -github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v0.0.0-20201006195004-351e25ade6e3/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= -github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4= github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -459,137 +334,87 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw= -github.com/quasilyte/go-ruleguard v0.2.1 h1:56eRm0daAyny9UhJnmtJW/UyLZQusukBAB8oT8AHKHo= github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= -github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.1.0/go.mod h1:4O8tr7hBODaGE6VIhfJDHcwzh5GUccKSJBU0UMXJFVM= -github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro= github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ= -github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= -github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= -github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 h1:iGnD/q9160NWqKZZ5vY4p0dMiYMRknzctfSkqA4nBDw= github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug= -github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= -github.com/tetafro/godot v1.3.2 h1:HzWC3XjadkyeuBZxkfAFNY20UVvle0YD51I6zf6RKlU= github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= -github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 h1:Zn+mA4qTRyao2Petd+YovKaFOUuxDj158kqCIqvwTow= github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= -github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756 h1:zV5mu0ESwb+WnzqVaW2z1DdbAP0S46UtjY8DHQupQP4= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= -github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65 h1:Y0bLA422kvb32uZI4fy/Plop/Tbld0l9pSzl+j1FWok= github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= -github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= @@ -597,9 +422,7 @@ github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -629,7 +452,6 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -652,7 +474,6 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -669,7 +490,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -717,9 +537,7 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -731,18 +549,15 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d h1:MiWWjyhUzZ+jvhZvloX6ZrUsdEghn8a64Upd8EMHglE= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -751,7 +566,6 @@ golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -786,7 +600,6 @@ golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200731060945-b5fad4ed8dd6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= @@ -794,16 +607,13 @@ golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2 h1:vEtypaVub6UvKkiXZ2xx9QIvp9TL7sI7xp7vdi2kezA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -837,17 +647,13 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -856,27 +662,17 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= -howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= -mvdan.cc/gofumpt v0.0.0-20200802201014-ab5a8192947d/go.mod h1:bzrjFmaD6+xqohD3KYP0H2FEuxknnBmyyOxdhLdaIws= -mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475 h1:5ZmJGYyuTlhdlIpRxSFhdJqkXQweXETFCEaLhRAX3e8= mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0= -mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= -mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY= mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= From 66cf8126663797e868cbcf8ab95648d1d60ef9bc Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 21 Apr 2021 15:43:30 -0700 Subject: [PATCH 097/115] Update README with package uninstall instructions (#16) --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 72fa217b81..0ae2904143 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,37 @@ After successful notarization, the generated "ticket" is automatically stapled t Windows packaging utilizes Docker containers to run the WiX packaging tools. This should enable building Windows packages from any operating system that supports Docker. Please file an issue for any packaging-related issues. +### Uninstall + +Use the following procedures to stop the Orbit service and clean up the installed files. + +#### macOS (Pkg package) + +``` sh +sudo launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist +sudo rm -rf /var/lib/orbit /Library/LaunchDaemons/com.fleetdm.orbit.plist /usr/local/bin/orbit +``` + +#### Debian/Ubuntu (Deb package) + +``` sh +sudo systemctl stop orbit.service +sudo rm -rf /var/lib/orbit /usr/local/bin/orbit /lib/systemd/system/orbit.service +sudo dpkg -r orbit-osquery +``` + +#### CentOS/Red Hat (RPM package) + +``` sh +sudo systemctl stop orbit.service +sudo rm -rf /var/lib/orbit /usr/local/bin/orbit /lib/systemd/system/orbit.service +sudo rpm -e orbit-osquery +``` + +#### Windows (MSI package) + +Use the standard "Add and Remove Programs" dialog to uninstall on Windows. + ## FAQs ### How does Orbit compare with Kolide Launcher? From 23e1d0e2e66132234ced05e8ec6475ac59108ff6 Mon Sep 17 00:00:00 2001 From: stephenenelson Date: Fri, 23 Apr 2021 18:03:48 -0700 Subject: [PATCH 098/115] Write Fleet certificate into Linux package if needed (#17) Fix for fleetdm/fleet#674. Adds the pem file into Linux packages as needed. --- pkg/packaging/linux_shared.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/packaging/linux_shared.go b/pkg/packaging/linux_shared.go index d1ccc8ab42..2a1c5f95bb 100644 --- a/pkg/packaging/linux_shared.go +++ b/pkg/packaging/linux_shared.go @@ -65,6 +65,12 @@ func buildNFPM(opt Options, pkger nfpm.Packager) error { return errors.Wrap(err, "write postinstall script") } + if opt.FleetCertificate != "" { + if err := writeCertificate(opt, orbitRoot); err != nil { + return errors.Wrap(err, "write fleet certificate") + } + } + // Pick up all file contents contents := files.Contents{ From 1140a04aaf2da6eec9013ee02ef28e92ea88f586 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Fri, 23 Apr 2021 18:08:12 -0700 Subject: [PATCH 099/115] Update go.sum file for all platforms (#18) Fixes golangci-lint --- go.sum | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) diff --git a/go.sum b/go.sum index 7dc47ae791..270fb6fe89 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw= 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= @@ -5,126 +6,216 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Djarvur/go-err113 v0.1.0 h1:uCRZZOdMQ0TZPHYTdYpoC0bLYJKPEHPUJ8MeAa51lNU= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= +github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= +github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/ashanbrown/forbidigo v1.0.0 h1:QdNXBduDUopc3GW+YVYZn8jzmIMklQiCfdN2N5+dQeE= github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyafc3ntEGh2BBAg= +github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a h1:/U9tbJzDRof4fOR51vwzWdIBsIH6R2yU0KG1MBRM2Js= github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8= github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RSSp2Om9lubZpiMgVbvn39bsUmW9U5h0twqc= github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/daixiang0/gci v0.2.7 h1:bosLNficubzJZICsVzxuyNc6oAbdz0zcqLG2G/RxtY4= github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e h1:Ss/B3/5wWRh8+emnK0++g5zQzwDTi30W10pKxKc4JXI= github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-critic/go-critic v0.5.2 h1:3RJdgf6u4NZUumoP8nzbqiiNT8e1tC2Oc7jlgqre/IA= github.com/go-critic/go-critic v0.5.2/go.mod h1:cc0+HvdE3lFpqLecgqMaJcvWWH77sLdBp+wLGPM1Yyo= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= +github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0SDS/gQ= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.0 h1:4DFWWMXVfbcN5So1sBNW9+yeiMqLFGl1wFLTL5R0Tgg= github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -140,23 +231,38 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpcLLt7aSj/odlKrSrelQwlovBpDuf19w= github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= +github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= +github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d h1:pXTK/gkVNs7Zyy7WKgLXmpQ5bHTrq5GDsp8R9Qs67g0= github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.34.1 h1:xf1yVlLBNeCIoOHWXhwqnUeaqzONllRSgiLSahNt0Mw= github.com/golangci/golangci-lint v1.34.1/go.mod h1:6Bnn7T0JYin7uukitgL6f9E9auQatlT0RMNOKG9lSHU= +github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= github.com/golangci/misspell v0.0.0-20180809174111-950f5d19e770/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= github.com/golangci/revgrep v0.0.0-20180526074752-d9c87f5ffaf0/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039 h1:XQKc8IYQOeRwVs36tDrEmTgDgP88d5iEURwpmtiAlOM= github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunEYvmd/TLamH+7LlVccLvUH5kZNhbCgTHoBbp4= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -165,277 +271,468 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688 h1:jyGRCFMyDK/gKe6QRZQWci5+wEUBFElvxLHs3iwO3hY= github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/goreleaser/chglog v0.1.2 h1:tdzAb/ILeMnphzI9zQ7Nkq+T8R9qyXli8GydD8plFRY= github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8= +github.com/goreleaser/fileglob v0.3.1 h1:OTFDWqUUHjQazk2N5GdUqEbqT/grBnRARaAXsV07q1Y= github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= +github.com/goreleaser/nfpm/v2 v2.2.2 h1:aLGEqhMDcSNg1RHwzUBHwRUbmiK8HfD1sTq8bG7/WMc= github.com/goreleaser/nfpm/v2 v2.2.2/go.mod h1:WtPzYQh+Ls57prS9RzXegrGejqILUS1aZibXHTTJ8eI= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= +github.com/gostaticanalysis/analysisutil v0.6.1 h1:/1JkoHe4DVxur+0wPvi26FoQfe1E3ZGqIXS3aaSLiaw= github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2 h1:STV8OvzphW1vlhPFxcG8d6OIilzBSKRAoWFJt+Onu10= github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.6.3 h1:tuulM+WnToeqa05z83YLmKabZxrySOmJAd4mJ+s2Nfg= github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg= github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5 h1:lrdPtrORjGv1HbbEvKWDUAy97mPpFm4B8hp77tcCUJY= github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk= github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/maratori/testpackage v1.0.1 h1:QtJ5ZjqapShm0w5DosRjg0PRlSdAdlx+W6cCKoALdbQ= github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e h1:2U5rOmpaB96l35w+NDjMtmmrp2e6a6AJKoc4B5+7UwA= github.com/matoous/godox v0.0.0-20200801072554-4fb83dc2941e/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.1.0 h1:4ykwscnAFeHJruT+EY3M3vdeP8uXMh0VV2E61iR7XD8= github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo= github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8= +github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.0 h1:7ks8ZkOP5/ujthUsT07rNv+nkLXCQWKNHuwzOAesEks= github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee h1:1xJ+Xi9lYWLaaP4yB67ah0+548CD3110mCPWhVVjFkI= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= +github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.1.0 h1:kVlMw8h2LHPMGUVqUj6230oQjjTMFjwcZrnkhXzFfl8= github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4= github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= +github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw= +github.com/quasilyte/go-ruleguard v0.2.1 h1:56eRm0daAyny9UhJnmtJW/UyLZQusukBAB8oT8AHKHo= github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc85CVZro= github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= +github.com/securego/gosec/v2 v2.5.0 h1:kjfXLeKdk98gBe2+eYRFMpC4+mxmQQtbidpiiOQ69Qc= github.com/securego/gosec/v2 v2.5.0/go.mod h1:L/CDXVntIff5ypVHIkqPXbtRpJiNCh6c6Amn68jXDjo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= +github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.5.1 h1:VHu76Lk0LSP1x254maIu2bplkWpfBWI+B+6fdoZprcg= github.com/spf13/afero v1.5.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.1.1 h1:KfztREH0tPxJJ+geloSLaAkaPkr4ki2Er5quFV1TDo4= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/ssgreg/nlreturn/v2 v2.1.0 h1:6/s4Rc49L6Uo6RLjhWZGBpWWjfzk2yrf1nIW8m4wgVA= github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613 h1:iGnD/q9160NWqKZZ5vY4p0dMiYMRknzctfSkqA4nBDw= github.com/tent/canonical-json-go v0.0.0-20130607151641-96e4ba3a7613/go.mod h1:g6AnIpDSYMcphz193otpSIzN+11Rs+AAIIC6rm1enug= +github.com/tetafro/godot v1.3.2 h1:HzWC3XjadkyeuBZxkfAFNY20UVvle0YD51I6zf6RKlU= github.com/tetafro/godot v1.3.2/go.mod h1:ah7jjYmOMnIjS9ku2krapvGQrFNtTLo9Z/qB3dGU1eU= +github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 h1:Zn+mA4qTRyao2Petd+YovKaFOUuxDj158kqCIqvwTow= github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55/go.mod h1:L+uU/NRFK/7h0NYAnsmvsX9EghDB5QVCcHCIrK2h5nw= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= +github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756 h1:zV5mu0ESwb+WnzqVaW2z1DdbAP0S46UtjY8DHQupQP4= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= +github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65 h1:Y0bLA422kvb32uZI4fy/Plop/Tbld0l9pSzl+j1FWok= github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.4 h1:If7Va4cM03mpgrNH9k49/VOicWpGoG70XPBFFODYDsg= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= +github.com/valyala/quicktemplate v1.6.3 h1:O7EuMwuH7Q94U2CXD6sOX8AYHqQqWtmIk690IhmpkKA= github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.1.0 h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= +go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -452,13 +749,16 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -466,14 +766,17 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -503,6 +806,7 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPe golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -511,6 +815,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -553,13 +858,16 @@ golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -610,19 +918,23 @@ golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4X golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201121010211-780cb80bd7fb/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2 h1:vEtypaVub6UvKkiXZ2xx9QIvp9TL7sI7xp7vdi2kezA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -632,9 +944,11 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -643,17 +957,25 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -662,17 +984,26 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc= honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY= +howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= +mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475 h1:5ZmJGYyuTlhdlIpRxSFhdJqkXQweXETFCEaLhRAX3e8= mvdan.cc/gofumpt v0.0.0-20201129102820-5c11c50e9475/go.mod h1:E4LOcu9JQEtnYXtB1Y51drqh2Qr2Ngk9J3YrRCwcbd0= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY= mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= From 8c0d3313f03da2cd75e686e83a1f2a9af70ed15c Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 26 Apr 2021 17:47:39 -0700 Subject: [PATCH 100/115] Properly set update channels in MSI packaging (#19) Channels were not set in the Orbit invocation causing Orbit to always default to the 'stable' channels. --- pkg/packaging/windows_templates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/packaging/windows_templates.go b/pkg/packaging/windows_templates.go index bc07500700..a0e9bf9290 100644 --- a/pkg/packaging/windows_templates.go +++ b/pkg/packaging/windows_templates.go @@ -52,7 +52,7 @@ var windowsWixTemplate = template.Must(template.New("").Option("missingkey=error ErrorControl="ignore" Start="auto" Type="ownProcess" - Arguments='--root-dir "[ORBITROOT]." --log-file "[ORBITROOT]orbit-log.txt" {{ if .FleetURL }}--fleet-url "{{ .FleetURL }}"{{ end }} {{ if .EnrollSecret }}--enroll-secret-path "[ORBITROOT]secret.txt"{{ end }} {{if .Insecure }}--insecure{{ end }} {{ if .UpdateURL }}--update-url "{{ .UpdateURL }}"{{ end }}' + Arguments='--root-dir "[ORBITROOT]." --log-file "[ORBITROOT]orbit-log.txt" {{ if .FleetURL }}--fleet-url "{{ .FleetURL }}"{{ end }} {{ if .EnrollSecret }}--enroll-secret-path "[ORBITROOT]secret.txt"{{ end }} {{if .Insecure }}--insecure{{ end }} {{ if .UpdateURL }}--update-url "{{ .UpdateURL }}" {{ end }} --orbit-channel "{{ .OrbitChannel }}" --osqueryd-channel "{{ .OsquerydChannel }}"' > Date: Mon, 26 Apr 2021 18:17:24 -0700 Subject: [PATCH 101/115] Truncate database during open if necessary (#20) In certain non-clean shutdown scenarios, Badger will refuse to start up without calling truncate. If this is necessary, do so and log about possible data loss. Actual data loss is unlikely at this point due to limited use of the Badger database. --- cmd/orbit/orbit.go | 14 ++++++++++++-- go.mod | 1 + go.sum | 6 ++++++ pkg/database/database.go | 22 +++++++++++++++++++++- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 8ff79f8aa0..9cfdd2224d 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/dgraph-io/badger" "github.com/fleetdm/orbit/pkg/certificate" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" @@ -151,9 +152,18 @@ func main() { return errors.Wrap(err, "initialize root dir") } - db, err := database.Open(filepath.Join(c.String("root-dir"), "orbit.db")) + dbPath := filepath.Join(c.String("root-dir"), "orbit.db") + db, err := database.Open(dbPath) if err != nil { - return err + if errors.Is(err, badger.ErrTruncateNeeded) { + db, err = database.OpenTruncate(dbPath) + if err != nil { + return err + } + log.Warn().Msg("Open badger required truncate. Data loss is possible.") + } else { + return err + } } defer func() { if err := db.Close(); err != nil { diff --git a/go.mod b/go.mod index df417fe636..c5bf234e87 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/fleetdm/orbit go 1.15 require ( + github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.2 github.com/fatih/color v1.10.0 github.com/goreleaser/nfpm/v2 v2.2.2 diff --git a/go.sum b/go.sum index 270fb6fe89..bb19dbf2fa 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= @@ -127,8 +129,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= +github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= @@ -414,6 +419,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= diff --git a/pkg/database/database.go b/pkg/database/database.go index 100377348d..ac3481b54b 100644 --- a/pkg/database/database.go +++ b/pkg/database/database.go @@ -22,7 +22,7 @@ type BadgerDB struct { closeChan chan struct{} } -// Open opens (initializing if necessary) a new Badger database at the specified +// Open opens (initializing if necessary) a Badger database at the specified // path. Users must close the DB with Close(). func Open(path string) (*BadgerDB, error) { // DefaultOptions sets synchronous writes to true (maximum data integrity). @@ -38,6 +38,26 @@ func Open(path string) (*BadgerDB, error) { return b, nil } +// OpenTruncate opens (initializing and/or truncating if necessary) a Badger +// database at the specified path. Users must close the DB with Close(). +// +// Prefer Open in the general case, but after a bad shutdown it may be necessary +// to call OpenTruncate. This may cause data loss. Detect this situation by +// looking for badger.ErrTruncateNeeded. +func OpenTruncate(path string) (*BadgerDB, error) { + // DefaultOptions sets synchronous writes to true (maximum data integrity). + // TODO implement logging? + db, err := badger.Open(badger.DefaultOptions(path).WithLogger(nil).WithTruncate(true)) + if err != nil { + return nil, errors.Wrapf(err, "open badger with truncate %s", path) + } + + b := &BadgerDB{DB: db} + b.startBackgroundCompaction() + + return b, nil +} + // startBackgroundCompaction starts a background loop that will call the // compaction method on the database. Badger does not do this automatically, so // we need to be sure to do so here (or elsewhere). From 79e82ebcb653b435c6753c68a42cadaa083115f7 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Mon, 26 Apr 2021 18:26:45 -0700 Subject: [PATCH 102/115] Fix Windows enroll secret permissions (#21) Properly set the permissions to prevent normal users from reading the enroll secret deployed by a Windows Orbit MSI. Improved inline documentation on the permission settings. --- pkg/packaging/wix/transform.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/packaging/wix/transform.go b/pkg/packaging/wix/transform.go index e95a935efd..d2f65ed33b 100644 --- a/pkg/packaging/wix/transform.go +++ b/pkg/packaging/wix/transform.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/xml" "io/ioutil" + "strings" "github.com/pkg/errors" ) @@ -84,11 +85,22 @@ func transform(cur *node, stack *[]*node) error { // Using this cryptic string seems to be the only way to disable // permission inheritance in a WiX package, so we may not have // any option for something more readable. + // + // Permissions: + // Disable inheritance + // SYSTEM: read/write/execute + // Administrators: read/write/execute + // Users: read/execute sddl := "O:SYG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)" - if cur.Attrs.Get("Name") == "secret.txt" { - // This SDDL copied from properly configured file on a Windows - // 10 machine. Permissions are same as below but with read - // access removed for regular users. + if strings.HasSuffix(cur.Attrs.Get("Source"), "secret.txt") { + // This SDDL copied from properly configured file on a Windows 10 + // machine. Permissions are same as above but with access removed + // for regular users. + // + // Permissions: + // Disable inheritance + // SYSTEM: read/write/execute + // Administrators: read/write/execute sddl = "O:SYG:SYD:PAI(A;;FA;;;SY)(A;;FA;;;BA)" } From 4d8f78241e3019f9001f199ee5a751934ca29182 Mon Sep 17 00:00:00 2001 From: noahtalerman <47070608+noahtalerman@users.noreply.github.com> Date: Tue, 4 May 2021 15:55:21 -0400 Subject: [PATCH 103/115] Remove usage and packaging documentation. Link to Fleet repo (#22) The goal of this PR is to move the "Usage" and "Packaging" sections of the Orbit documentation to the Fleet repo. This way, Fleet users can remain in the Fleet docs when reading Orbit documentation. Eventually, when the Fleet docs move to fleetdm.com, the Orbit documentation will live on the website as well. --- README.md | 182 ++---------------------------------------------------- 1 file changed, 6 insertions(+), 176 deletions(-) diff --git a/README.md b/README.md index 0ae2904143..99fad369e5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Orbit is an [osquery](https://github.com/osquery/osquery) runtime and autoupdater. With Orbit, it's easy to deploy osquery, manage configurations, and stay up to date. Orbit eases the deployment of osquery connected with a [Fleet server](https://github.com/fleetdm/fleet), and is a (near) drop-in replacement for osquery in a variety of deployment scenarios. -Orbit is the recommended agent for Fleet. But Orbit can be used with or without Fleet, and Fleet can be used with or without Orbit. +Orbit is the recommended agent for Fleet. But Orbit can be used with or without Fleet, and Fleet can be used with or without Orbit. ## Try Orbit @@ -15,13 +15,15 @@ Orbit is the recommended agent for Fleet. But Orbit can be used with or without # Generate a macOS installer pointed at your local Fleet go run ./cmd/package --type=pkg --fleet-url=localhost:8412 --insecure --enroll-secret=YOUR_FLEET_ENROLL_SECRET_HERE ``` + > With fleetctl preview running, you can find your Fleet enroll secret by selecting the "Add new host" button on the Hosts page in the Fleet UI. An installer configured to point at your Fleet instance has now been generated. -Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. Refresh after several seconds (≈30s), and you should now see your local computer as a new host in Fleet. +Now run that installer (double click, on a Mac) to enroll your own computer as a host in Fleet. Refresh after several seconds (≈30s), and you should now see your local computer as a new host in Fleet. ## Bugs + To report a bug or request a feature, [click here](https://github.com/fleetdm/fleet/issues). ## Capabilities @@ -41,182 +43,10 @@ To report a bug or request a feature, [click here](https://github.com/fleetdm/fl ## Usage +[The up-to-date documentation for Orbit is maintained in the Fleet repository.](https://github.com/fleetdm/fleet/blob/master/docs/2-Orbit-osquery/README.md) + General information and flag documentation can be accessed by running `orbit --help`. -### Permissions - -Orbit generally expects root permissions to be able to create and access it's working files. - -To get root level permissions: - -#### macOS/Linux - -Prefix `orbit` commands with `sudo` (`sudo orbit ...`) or run in a root shell. - -#### Windows - -Run Powershell or cmd.exe with "Run as administrator" and start `orbit` commands from that shell. - -### Osquery shell - -Run an `osqueryi` shell with `orbit osqueryi` or `orbit shell`. - -### Connect to a Fleet server - -Use the `--fleet-url` and `--enroll-secret` flags to connect to a Fleet server. - -For example: - -``` sh -orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value -``` - -Use `--fleet_certificate` to provide a path to a certificate bundle when necessary for osquery to verify the authenticity of the Fleet server (typically when using a Windows client or self-signed certificates): - -``` sh -orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --fleet-certificate=cert.pem -``` - -Add the `--insecure` flag for connections using otherwise invalid certificates: - -``` sh -orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --insecure -``` - -### Osquery flags - -Orbit can be used as near drop-in replacement for `osqueryd`, enhancing standard osquery with autoupdate capabilities. Orbit passes through any options after `--` directly to the `osqueryd` instance. - -For example, the following would be a typical drop-in usage of Orbit: - -``` sh -orbit -- --flagfile=flags.txt -``` - -## Packaging - -Orbit, like standalone osquery, is typically deployed via OS-specific packages. Tooling is provided with this repository to generate installation packages. - -### Packaging support - -- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) and codesigning - Persistence via `launchd`. - -- **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. - -- **Windows** - `.msi` package generation - Persistence via Services. - -### Building packages - -Before building packages, clone or download this repository and [install Go](https://golang.org/doc/install). - -Use `go run ./cmd/package` from this directory to run the packaging tools. - -The only required parameter is `--type`, use one of `deb`, `rpm`, or `pkg` (`msi` coming soon). - -Configure osquery to connect to a Fleet (or other TLS) server with the `--fleet-url` and `--enroll-secret` flags. - -A minimal invocation for communicating with Fleet: - -``` sh -go run ./cmd/package --type deb --fleet-url=fleet.example.com --enroll-secret=notsosecret -``` - -This will build a `.deb` package configured to communicate with a Fleet server at `fleet.example.com` using the enroll secret `notsosecret`. - -When the Fleet server uses a self-signed (or otherwise invalid) TLS certificate, package with the `--insecure` or `--fleet-certificate` options. - -See `go run ./cmd/package` for the full range of packaging options. - -#### Update channels - -Orbit uses the concept of "update channels" to determine the version of Orbit, osquery, and any extensions (extension support coming soon) to run. This concept is modeled from the common versioning convention for Docker containers. - -Configure update channels for Orbit and osqueryd with the `--orbit-channel` and `--osqueryd-channel` flags when packaging. - -| Channel | Versions | -| ------------------------------------ | ------ | -| `4` | 4.x.x | -| `4.6` | 4.6.x | -| `4.6.0` | 4.6.0 | - -Additionally `stable` and `edge` are special channel names. `stable` will always return the version Fleet deems to be stable, while `edge` will provide newer releases for beta testing. - -#### macOS signing & Notarization - -Orbit's packager can automate the codesigning and Notarization steps to allow the resulting package to generate packages that appear "trusted" when install on macOS hosts. Signing & notarization are supported only on macOS hosts. - -For signing, a "Developer ID Installer" certificate must be available on the build machine ([generation instructions](https://help.apple.com/xcode/mac/current/#/dev154b28f09)). Use `security find-identity -v` to verify the existence of this certificate and make note of the identifier provided in the left column. - -For Notarization, valid App Store Connect credentials must be available on the build machine. Set these in the environment variables `AC_USERNAME` and `AC_PASSWORD`. It is common to configure this via [app-specific passwords](https://support.apple.com/en-ca/HT204397). - -Build a signed and notarized macOS package with an invocation like the following: - -``` sh -AC_USERNAME=zach@fleetdm.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type=pkg --fleet-url=fleet.example.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize -``` - -This process may take several minutes to complete as the Notarization process completes on Apple's servers. - -After successful notarization, the generated "ticket" is automatically stapled to the package. - -#### Windows packaging - -Windows packaging utilizes Docker containers to run the WiX packaging tools. This should enable building Windows packages from any operating system that supports Docker. Please file an issue for any packaging-related issues. - -### Uninstall - -Use the following procedures to stop the Orbit service and clean up the installed files. - -#### macOS (Pkg package) - -``` sh -sudo launchctl unload /Library/LaunchDaemons/com.fleetdm.orbit.plist -sudo rm -rf /var/lib/orbit /Library/LaunchDaemons/com.fleetdm.orbit.plist /usr/local/bin/orbit -``` - -#### Debian/Ubuntu (Deb package) - -``` sh -sudo systemctl stop orbit.service -sudo rm -rf /var/lib/orbit /usr/local/bin/orbit /lib/systemd/system/orbit.service -sudo dpkg -r orbit-osquery -``` - -#### CentOS/Red Hat (RPM package) - -``` sh -sudo systemctl stop orbit.service -sudo rm -rf /var/lib/orbit /usr/local/bin/orbit /lib/systemd/system/orbit.service -sudo rpm -e orbit-osquery -``` - -#### Windows (MSI package) - -Use the standard "Add and Remove Programs" dialog to uninstall on Windows. - -## FAQs - -### How does Orbit compare with Kolide Launcher? - -Orbit is inspired by the success of [Kolide Launcher](https://github.com/kolide/launcher), and approaches a similar problem domain with new strategies informed by the challenges encountered in real world deployments. Orbit does not share any code with Launcher. - -- Both Orbit and Launcher use [The Update Framework](https://theupdateframework.com/) specification for managing updates. Orbit utilizes the official [go-tuf](https://github.com/theupdateframework/go-tuf) library, while Launcher has it's own implementation of the specification. -- Orbit can be deployed as a (near) drop-in replacement for osquery, supporting full customization of the osquery flags. Launcher heavily manages the osquery flags making deployment outside of Fleet or Kolide's SaaS difficult. -- Orbit prefers the battle-tested plugins of osquery. Orbit uses the built-in logging, configuration, and live query plugins, while Launcher uses custom implementations. -- Orbit prefers the built-in osquery remote APIs. Launcher utilizes a custom gRPC API that has led to issues with character encoding, load balancers/proxies, and request size limits. -- Orbit encourages use of the osquery performance Watchdog, while Launcher disables the Watchdog. - -Additionally, Orbit aims to tackle problems out of scope for Launcher: - -- Configure updates via release channels, providing more granular control over agent versioning. -- Support for deploying and updating osquery extensions (🔜). -- Manage osquery versions and startup flags from a remote (Fleet) server (🔜). -- Further control of osquery performance via cgroups (🔜). - -### Is Orbit Free? - -Yes! Orbit is licensed under an MIT license and all uses are encouraged. - ## Community #### Chat From 224257107408b89855c4f22ee0577acc04957747 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 18 May 2021 10:36:35 -0700 Subject: [PATCH 104/115] Fix osqueryd channel reference in orbit shell (#23) Fixes an error "unknown target file" when running `orbit shell` as reported by a user on Slack. Add validation to the Updater.Get method. --- cmd/orbit/shell.go | 2 +- pkg/update/update.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cmd/orbit/shell.go b/cmd/orbit/shell.go index 9c92b288ff..245080047d 100644 --- a/cmd/orbit/shell.go +++ b/cmd/orbit/shell.go @@ -60,7 +60,7 @@ var shellCommand = &cli.Command{ if err := updater.UpdateMetadata(); err != nil { log.Info().Err(err).Msg("failed to update metadata. using saved metadata.") } - osquerydPath, err := updater.Get("osqueryd", c.String("osquery-channel")) + osquerydPath, err := updater.Get("osqueryd", c.String("osqueryd-channel")) if err != nil { return err } diff --git a/pkg/update/update.go b/pkg/update/update.go index 4980aa687d..257c6519a4 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -142,6 +142,13 @@ func (u *Updater) Targets() (data.TargetFiles, error) { // Get returns the local path to the specified target. The target is downloaded // if it does not yet exist locally or the hash does not match. func (u *Updater) Get(target, channel string) (string, error) { + if target == "" { + return "", errors.New("target is required") + } + if channel == "" { + return "", errors.New("channel is required") + } + localPath := u.LocalPath(target, channel) repoPath := u.RepoPath(target, channel) stat, err := os.Stat(localPath) From 97f22d965c1a33f5c510c6eaa7c16f83d1b19462 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 19 May 2021 17:16:42 -0700 Subject: [PATCH 105/115] Run go mod tidy (#24) --- go.mod | 7 ++- go.sum | 157 --------------------------------------------------------- 2 files changed, 3 insertions(+), 161 deletions(-) diff --git a/go.mod b/go.mod index c5bf234e87..b27b5aedc6 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,11 @@ module github.com/fleetdm/orbit go 1.15 require ( - github.com/dgraph-io/badger v1.6.2 // indirect + github.com/dgraph-io/badger v1.6.2 github.com/dgraph-io/badger/v2 v2.2007.2 github.com/fatih/color v1.10.0 github.com/goreleaser/nfpm/v2 v2.2.2 - github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect - github.com/kr/text v0.2.0 // indirect + github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 github.com/mitchellh/gon v0.2.3 github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 @@ -17,5 +16,5 @@ require ( github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55 github.com/urfave/cli/v2 v2.3.0 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect - golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect + golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 ) diff --git a/go.sum b/go.sum index bb19dbf2fa..822c7e99ff 100644 --- a/go.sum +++ b/go.sum @@ -6,25 +6,17 @@ cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSR cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3 h1:AVXDdKsrtX33oR9fbCMu/+c1o8Ofjq6Ku/MInaLVg5Y= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/firestore v1.1.0 h1:9x7Bx0A9R5/M9jibeJeZWqjeVEIxYW9fZYqB9a70/bY= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= -cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -48,35 +40,23 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQee8Us= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4= github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= -github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0= github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26FmByPp2eC2qla6E1Tw+scpcg/to= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= @@ -85,11 +65,8 @@ github.com/ashanbrown/forbidigo v1.0.0/go.mod h1:PH+zMRWE15yW69fYfe7Kn8nYR6yYyaf github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a h1:/U9tbJzDRof4fOR51vwzWdIBsIH6R2yU0KG1MBRM2Js= github.com/ashanbrown/makezero v0.0.0-20201205152432-7b7cdbb3025a/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c h1:+0HFd5KSZ/mm3JmhmrDukiId5iR6w4+BdFtfSy4yWIc= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= @@ -99,28 +76,20 @@ github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RS github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3q1JMazcgBQ= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible h1:bXhRBIXoTm9BYHS3gE0TtQuyNZyeEMux2sDi4oo5YOo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/daixiang0/gci v0.2.7 h1:bosLNficubzJZICsVzxuyNc6oAbdz0zcqLG2G/RxtY4= github.com/daixiang0/gci v0.2.7/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc= @@ -136,11 +105,9 @@ github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDm github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -150,14 +117,12 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e h1:Ss/B3/5wWRh8+emnK0++g5zQzwDTi30W10pKxKc4JXI= github.com/flynn/go-docopt v0.0.0-20140912013429-f6dd2ebbb31e/go.mod h1:HyVoz1Mz5Co8TFO8EupIdlcpwShBmY98dkT2xeHkvEI= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= @@ -171,20 +136,13 @@ github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbK github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= @@ -194,7 +152,6 @@ github.com/go-toolsmith/astequal v1.0.0 h1:4zxD8j3JRFNyLN46lodQuqz3xdKSrur7U/sr0 github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21 h1:wP6mXeB2V/d1P1K7bZ5vDUO3YqEzcvOREOxZPEu3gVI= github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= @@ -212,15 +169,11 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -267,7 +220,6 @@ github.com/golangci/revgrep v0.0.0-20180812185044-276a5c0a1039/go.mod h1:qOQCunE github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -278,12 +230,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688 h1:jyGRCFMyDK/gKe6QRZQWci5+wEUBFElvxLHs3iwO3hY= github.com/google/rpmpack v0.0.0-20201225075926-0a97c2c4b688/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk= @@ -291,9 +240,7 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gookit/color v1.3.1 h1:PPD/C7sf8u2L8XQPdPgsWRoAiLQGZEZOzU3cf5IYYUk= github.com/gookit/color v1.3.1/go.mod h1:R3ogXq2B9rTbXoSHJ1HyUVAZ3poOJHpd9nQmyGZsfvQ= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -303,7 +250,6 @@ github.com/goreleaser/fileglob v0.3.1 h1:OTFDWqUUHjQazk2N5GdUqEbqT/grBnRARaAXsV0 github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8= github.com/goreleaser/nfpm/v2 v2.2.2 h1:aLGEqhMDcSNg1RHwzUBHwRUbmiK8HfD1sTq8bG7/WMc= github.com/goreleaser/nfpm/v2 v2.2.2/go.mod h1:WtPzYQh+Ls57prS9RzXegrGejqILUS1aZibXHTTJ8eI= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= @@ -314,15 +260,10 @@ github.com/gostaticanalysis/analysisutil v0.6.1/go.mod h1:18U/DLpRgIUd459wGxVHE0 github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1 h1:xHopR5L2lRz6OsjH4R2HG5wRhW9ySl3FsHIvi5pcXwc= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/consul/api v1.1.0 h1:BNQPM9ytxj6jbjjdRPioQ94T6YXriSopn0i8COv6SRA= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/sdk v0.1.1 h1:LnuDWGNsoajlhGyHJvuWW6FVqRl8JOTPqS6CPTsYjhY= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -331,43 +272,29 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2 h1:STV8OvzphW1vlhPFxcG8d6OIilzBSKRAoWFJt+Onu10= github.com/hashicorp/go-hclog v0.9.3-0.20191025211905-234833755cb2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-retryablehttp v0.6.3 h1:tuulM+WnToeqa05z83YLmKabZxrySOmJAd4mJ+s2Nfg= github.com/hashicorp/go-retryablehttp v0.6.3/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go.net v0.0.1 h1:sNCoNyDEvN1xa+X0baata4RdcpKwcMS6DH+xwfqPgjw= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.0.0 h1:efQznTz+ydmQXq3BOnRa3AXzvCeTq1P4dKj/z5GLlY8= github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90= -github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 h1:S4qyfL2sEm5Budr4KVMyEniCy+PbS55651I/a+Kn/NQ= github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95/go.mod h1:QiyDdbZLaJ/mZP4Zwc9g2QsfaEA4o7XvvgZegSci5/E= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= @@ -378,7 +305,6 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg= github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= @@ -388,39 +314,27 @@ github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3/go.mod github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5 h1:lrdPtrORjGv1HbbEvKWDUAy97mPpFm4B8hp77tcCUJY= github.com/jmoiron/sqlx v1.2.1-0.20190826204134-d7d95172beb5/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.0 h1:wJbzvpYMVGG9iTI9VxpnNZfd4DzMPoCWze3GgSqz8yg= github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -429,13 +343,10 @@ github.com/kulti/thelper v0.1.0 h1:ig1EW6yhDiRNN3dplbhdsW2gTvbxTz9i4q5Rr/tRfpk= github.com/kulti/thelper v0.1.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U= github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= -github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= -github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -456,34 +367,24 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.1.0 h1:4ykwscnAFeHJruT+EY3M3vdeP8uXMh0VV2E61iR7XD8= github.com/mbilski/exhaustivestruct v1.1.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mitchellh/cli v1.0.0 h1:iGBIsUe3+HZ/AD/Vd7DErOt5sU9fa8Uj7A2s1aggv1Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= -github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gon v0.2.3 h1:fObN7hD14VacGG++t27GzTW6opP0lwI7TsgTPL55wBo= github.com/mitchellh/gon v0.2.3/go.mod h1:Ua18ZhqjZHg8VyqZo8kNHAY331ntV6nNJ9mT3s2mIo8= -github.com/mitchellh/gox v0.4.0 h1:lfGJxY7ToLJQjHHwi0EX6uYBdK78egf954SQl13PQJc= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -493,15 +394,11 @@ github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= -github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee h1:1xJ+Xi9lYWLaaP4yB67ah0+548CD3110mCPWhVVjFkI= github.com/mozilla/tls-observatory v0.0.0-20200317151703-4fa42e1c2dee/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nakabonne/nestif v0.3.0 h1:+yOViDGhg8ygGrmII72nV9B/zGxY188TYpfolntsaPw= github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c= @@ -515,7 +412,6 @@ github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -529,9 +425,7 @@ github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c h1:Lgl0gzECD8GnQ5QCWA8o6BtfL6mDH5rQgM4/fX3avOs= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= @@ -542,29 +436,21 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f h1:xAw10KgJqG5NJDfmRqJ05Z0IFblKumjtMeyiOLxj3+4= github.com/polyfloyd/go-errorlint v0.0.0-20201127212506-19bd8db6546f/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw= -github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c h1:JoUA0uz9U0FVFq5p4LjEq4C0VgQ0El320s3Ms0V4eww= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-ruleguard v0.2.0/go.mod h1:2RT/tf0Ce0UDj5y243iWKosQogJd8+1G3Rs2fxmlYnw= github.com/quasilyte/go-ruleguard v0.2.1 h1:56eRm0daAyny9UhJnmtJW/UyLZQusukBAB8oT8AHKHo= @@ -572,13 +458,10 @@ github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwq github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c h1:+gtJ/Pwj2dgUGlZgTrNFqajGYKZQc7Piqus/S6DK9CE= github.com/quasilyte/regex/syntax v0.0.0-20200805063351-8f842688393c/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= @@ -590,11 +473,9 @@ github.com/ryancurrah/gomodguard v1.2.0 h1:YWfhGOrXwLGiqcC/u5EqG6YeS8nh+1fw0HEc8 github.com/ryancurrah/gomodguard v1.2.0/go.mod h1:rNqbC4TOIdUDcVMSIpNNAzTbzXAZa6W5lnUepvuMMgQ= github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f h1:UFr9zpz4xgTnIE5yIMtWAMngCdZ9p/+q6lTbgelo80M= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= @@ -605,13 +486,9 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= -github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada h1:WokF3GuxBeL+n4Lk4Fa8v9mbdjlrl7bHuneF4N1bk2I= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= -github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 h1:udFKJ0aHUL60LboW/A+DfgoHVedieIzIXE8uylPue0U= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -625,7 +502,6 @@ github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsR github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= @@ -669,7 +545,6 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b h1:HxLVTlqcHhFAz3nWUcuvpH7WuOMv8LQoCWmruLfFH2U= @@ -683,14 +558,12 @@ github.com/theupdateframework/go-tuf v0.0.0-20201230183259-aee6270feb55/go.mod h github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94 h1:ig99OeTyDwQWhPe2iw9lwfQVF1KB3Q4fpP3X7/2VBG8= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck v0.0.0-20200807122107-df9e8bcb914d/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756 h1:zV5mu0ESwb+WnzqVaW2z1DdbAP0S46UtjY8DHQupQP4= github.com/tomarrell/wrapcheck v0.0.0-20201130113247-1683564d9756/go.mod h1:yiFB6fFoV7saXirUGfuK+cPtUh4NX/Hf5y2WC2lehu0= github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65 h1:Y0bLA422kvb32uZI4fy/Plop/Tbld0l9pSzl+j1FWok= github.com/tommy-muehle/go-mnd v1.3.1-0.20201008215730-16041ac3fe65/go.mod h1:T22e7iRN4LsFPZGyRLRXeF+DWVXFuV9thsyO7NjbbTI= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8 h1:3SVOIvH7Ae1KRYyQWRjXWJEA9sS/c/pjvH++55Gr648= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= @@ -703,42 +576,28 @@ github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/uudashr/gocognit v1.0.1 h1:MoG2fZ0b/Eo7NXoIwCVFLG5JED3qgQz5/NEE+rOsjPs= github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= -github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.16.0 h1:9zAqOYLl8Tuy3E5R6ckzGDJ1g8+pw15oQp2iL9Jl6gQ= github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= -github.com/valyala/quicktemplate v1.6.3 h1:O7EuMwuH7Q94U2CXD6sOX8AYHqQqWtmIk690IhmpkKA= github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a h1:0R4NLDRDZX6JcmhJgXi5E4b8Wg84ihbmUKp/GvSPEzc= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v1.1.0 h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= -go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -761,10 +620,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -772,10 +629,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= @@ -812,7 +667,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11 h1:lwlPPsmjDKK0J6eG6xDWd5XPe golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -821,7 +675,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -873,7 +726,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -935,12 +787,10 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0 h1:Q3Ui3V3/CVinFWFiW39Iw0kMuVrRzYX0wN6OPFp0lTA= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -950,11 +800,9 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -963,21 +811,17 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1011,5 +855,4 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY= mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= -rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= From 54b4bcbfd46b06afca9ffd420a9d236f0eb37ce9 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Thu, 20 May 2021 08:15:34 -0700 Subject: [PATCH 106/115] Ensure consistency of Badger imports (#25) Accidentally importing multiple versions of Badger caused warnings to be output about protobuf registration. Fixes https://github.com/fleetdm/fleet/issues/811 --- cmd/orbit/orbit.go | 2 +- go.mod | 1 - go.sum | 6 ------ 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/cmd/orbit/orbit.go b/cmd/orbit/orbit.go index 9cfdd2224d..6fe7f89764 100644 --- a/cmd/orbit/orbit.go +++ b/cmd/orbit/orbit.go @@ -12,7 +12,7 @@ import ( "strings" "time" - "github.com/dgraph-io/badger" + "github.com/dgraph-io/badger/v2" "github.com/fleetdm/orbit/pkg/certificate" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/database" diff --git a/go.mod b/go.mod index b27b5aedc6..8748a8062c 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/fleetdm/orbit go 1.15 require ( - github.com/dgraph-io/badger v1.6.2 github.com/dgraph-io/badger/v2 v2.2007.2 github.com/fatih/color v1.10.0 github.com/goreleaser/nfpm/v2 v2.2.2 diff --git a/go.sum b/go.sum index 822c7e99ff..7e0d3c2b0c 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,6 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= -github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -98,11 +96,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denis-tingajkin/go-header v0.4.2 h1:jEeSF4sdv8/3cT/WY8AgDHUoItNSoEZ7qg9dX7pc218= github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA= -github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= -github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= -github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -334,7 +329,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= From 8fd69dcc2546a8a0e8518b77cd87814ba3d1eee1 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 22 Jun 2021 11:25:18 -0700 Subject: [PATCH 107/115] Fix build of Windows MSI on Linux (#27) A bug in the platform detection logic allowed this to work appropriately on macOS (by lucky chance that `runtime.GOOS != constant.PlatformName`), but failed on Linux. This is fixed by properly comparing the platform of the downloaded binary with the platform we are currently running on, and only checking the binary execution if they match. Fixes https://github.com/fleetdm/fleet/issues/1144 --- pkg/update/update.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/update/update.go b/pkg/update/update.go index 257c6519a4..5a9176880d 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -9,7 +9,6 @@ import ( "os/exec" "path" "path/filepath" - "runtime" "github.com/fleetdm/orbit/pkg/constant" "github.com/fleetdm/orbit/pkg/platform" @@ -224,15 +223,17 @@ func (u *Updater) Download(repoPath, localPath string) error { return errors.Wrap(err, "close tmp file") } - if runtime.GOOS == constant.PlatformName { + // Attempt to exec the new binary only if the platform matches. This will + // always fail if the binary doesn't match the platform, so there's not + // really anything we can check. + if u.opt.Platform == constant.PlatformName { out, err := exec.Command(tmp.Name(), "--version").CombinedOutput() if err != nil { - return errors.Wrapf(err, "exec new version: %s", string(out)) } } - if runtime.GOOS == "windows" { + if constant.PlatformName == "windows" { // Remove old file first if err := os.Rename(localPath, localPath+".old"); err != nil && !os.IsNotExist(err) { return errors.Wrap(err, "rename old") From c4b2e7f45240b7deb8ef30a3cb55128f387339e5 Mon Sep 17 00:00:00 2001 From: noahtalerman <47070608+noahtalerman@users.noreply.github.com> Date: Mon, 5 Jul 2021 10:05:44 -0400 Subject: [PATCH 108/115] Bring "Usage," "Packaging," and FAQ sections back into Orbit repo (#26) This PR coincides with the restructuring of Fleet's documentation. fleetdm/fleet#1143 --- README.md | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99fad369e5..e25b18a824 100644 --- a/README.md +++ b/README.md @@ -43,10 +43,157 @@ To report a bug or request a feature, [click here](https://github.com/fleetdm/fl ## Usage -[The up-to-date documentation for Orbit is maintained in the Fleet repository.](https://github.com/fleetdm/fleet/blob/master/docs/2-Orbit-osquery/README.md) - General information and flag documentation can be accessed by running `orbit --help`. +### Permissions + +Orbit generally expects root permissions to be able to create and access it's working files. + +To get root level permissions: + +#### macOS/Linux + +Prefix `orbit` commands with `sudo` (`sudo orbit ...`) or run in a root shell. + +#### Windows + +Run Powershell or cmd.exe with "Run as administrator" and start `orbit` commands from that shell. + +### Osquery shell + +Run an `osqueryi` shell with `orbit osqueryi` or `orbit shell`. + +### Connect to a Fleet server + +Use the `--fleet-url` and `--enroll-secret` flags to connect to a Fleet server. + +For example: + +```sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value +``` + +Use `--fleet_certificate` to provide a path to a certificate bundle when necessary for osquery to verify the authenticity of the Fleet server (typically when using a Windows client or self-signed certificates): + +```sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --fleet-certificate=cert.pem +``` + +Add the `--insecure` flag for connections using otherwise invalid certificates: + +```sh +orbit --fleet-url=https://localhost:8080 --enroll-secret=the_secret_value --insecure +``` + +### Osquery flags + +Orbit can be used as near drop-in replacement for `osqueryd`, enhancing standard osquery with autoupdate capabilities. Orbit passes through any options after `--` directly to the `osqueryd` instance. + +For example, the following would be a typical drop-in usage of Orbit: + +```sh +orbit -- --flagfile=flags.txt +``` + +## Packaging + +Orbit, like standalone osquery, is typically deployed via OS-specific packages. Tooling is provided with this repository to generate installation packages. + +### Dependencies + +Orbit currently supports building packages on macOS and Linux. + +Before building packages, clone or download this repository and [install Go](https://golang.org/doc/install). + +Building Windows packages requires Docker to be installed. + +### Packaging support + +- **macOS** - `.pkg` package generation with (optional) [Notarization](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution) and codesigning - Persistence via `launchd`. + +- **Linux** - `.deb` (Debian, Ubuntu, etc.) & `.rpm` (RHEL, CentOS, etc.) package generation - Persistence via `systemd`. + +- **Windows** - `.msi` package generation - Persistence via Services. + +### Building packages + +Use `go run ./cmd/package` from this directory to run the packaging tools. + +The only required parameter is `--type`, use one of `deb`, `rpm`, `pkg`, or `msi`. + +Configure osquery to connect to a Fleet (or other TLS) server with the `--fleet-url` and `--enroll-secret` flags. + +A minimal invocation for communicating with Fleet: + +```sh +go run ./cmd/package --type deb --fleet-url=fleet.example.com --enroll-secret=notsosecret +``` + +This will build a `.deb` package configured to communicate with a Fleet server at `fleet.example.com` using the enroll secret `notsosecret`. + +When the Fleet server uses a self-signed (or otherwise invalid) TLS certificate, package with the `--insecure` or `--fleet-certificate` options. + +See `go run ./cmd/package` for the full range of packaging options. + +#### Update channels + +Orbit uses the concept of "update channels" to determine the version of Orbit, osquery, and any extensions (extension support coming soon) to run. This concept is modeled from the common versioning convention for Docker containers. + +Configure update channels for Orbit and osqueryd with the `--orbit-channel` and `--osqueryd-channel` flags when packaging. + +| Channel | Versions | +| ------- | -------- | +| `4` | 4.x.x | +| `4.6` | 4.6.x | +| `4.6.0` | 4.6.0 | + +Additionally `stable` and `edge` are special channel names. `stable` will always return the version Fleet deems to be stable, while `edge` will provide newer releases for beta testing. + +#### macOS signing & Notarization + +Orbit's packager can automate the codesigning and Notarization steps to allow the resulting package to generate packages that appear "trusted" when install on macOS hosts. Signing & notarization are supported only on macOS hosts. + +For signing, a "Developer ID Installer" certificate must be available on the build machine ([generation instructions](https://help.apple.com/xcode/mac/current/#/dev154b28f09)). Use `security find-identity -v` to verify the existence of this certificate and make note of the identifier provided in the left column. + +For Notarization, valid App Store Connect credentials must be available on the build machine. Set these in the environment variables `AC_USERNAME` and `AC_PASSWORD`. It is common to configure this via [app-specific passwords](https://support.apple.com/en-ca/HT204397). + +Build a signed and notarized macOS package with an invocation like the following: + +```sh +AC_USERNAME=zach@example.com AC_PASSWORD=llpk-sije-kjlz-jdzw go run ./cmd/package --type=pkg --fleet-url=fleet.example.com --enroll-secret=63SBzTT+2UyW --sign-identity 3D7260BF99539C6E80A94835A8921A988F4E6498 --notarize +``` + +This process may take several minutes to complete as the Notarization process completes on Apple's servers. + +After successful notarization, the generated "ticket" is automatically stapled to the package. + +## FAQs + +### How does Orbit compare with Kolide Launcher? + +Orbit is inspired by the success of [Kolide Launcher](https://github.com/kolide/launcher), and approaches a similar problem domain with new strategies informed by the challenges encountered in real world deployments. Orbit does not share any code with Launcher. + +- Both Orbit and Launcher use [The Update Framework](https://theupdateframework.com/) specification for managing updates. Orbit utilizes the official [go-tuf](https://github.com/theupdateframework/go-tuf) library, while Launcher has it's own implementation of the specification. +- Orbit can be deployed as a (near) drop-in replacement for osquery, supporting full customization of the osquery flags. Launcher heavily manages the osquery flags making deployment outside of Fleet or Kolide's SaaS difficult. +- Orbit prefers the battle-tested plugins of osquery. Orbit uses the built-in logging, configuration, and live query plugins, while Launcher uses custom implementations. +- Orbit prefers the built-in osquery remote APIs. Launcher utilizes a custom gRPC API that has led to issues with character encoding, load balancers/proxies, and request size limits. +- Orbit encourages use of the osquery performance Watchdog, while Launcher disables the Watchdog. + +Additionally, Orbit aims to tackle problems out of scope for Launcher: + +- Configure updates via release channels, providing more granular control over agent versioning. +- Support for deploying and updating osquery extensions (🔜). +- Manage osquery versions and startup flags from a remote (Fleet) server (🔜). +- Further control of osquery performance via cgroups (🔜). + +### Is Orbit Free? + +Yes! Orbit is licensed under an MIT license and all uses are encouraged. + +### How does orbit update osquery? And how do the stable and edge channels get triggered to update osquery on a self hosted Fleet instance? + +Orbit uses a configurable update server. We expect that many folks will just use the update server we manage (similar to what Kolide does with Launcher's update server). We are also offering [tooling for self-managing an update server](https://github.com/fleetdm/fleet/blob/master/docs/3-Deployment/4-fleetctl-agent-updates.md) as part of Fleet Basic (the subscription offering). + ## Community #### Chat From d56042de6a468f810b8faa0e4c96837f4bd20e91 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Tue, 20 Jul 2021 14:41:05 -0700 Subject: [PATCH 109/115] Fix build of Windows MSI when running as root (#28) Use permissive file permissions to allow mounting files into Wix Docker container. Fixes https://github.com/fleetdm/fleet/issues/1424 --- README.md | 2 +- changes/.keep | 1 + changes/build-msi-root | 1 + cmd/package/package.go | 2 +- pkg/packaging/packaging.go | 15 +++++++++++++++ pkg/packaging/windows.go | 5 +++++ 6 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 changes/.keep create mode 100644 changes/build-msi-root diff --git a/README.md b/README.md index e25b18a824..6fc1033c0c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Orbit is the recommended agent for Fleet. But Orbit can be used with or without ## Try Orbit -#### With [`fleetctl preview` already running](https://github.com/fleetdm/fleet#try-fleet) and [Go](https://golang.org/doc/install) installed: +#### With [`fleetctl preview` already running](https://github.com/fleetdm/fleet#try-fleet) and [Go](https://golang.org/doc/install) 1.16 installed: ```bash # From within the top-level directory of this repo… diff --git a/changes/.keep b/changes/.keep new file mode 100644 index 0000000000..cbf488f213 --- /dev/null +++ b/changes/.keep @@ -0,0 +1 @@ +IGNORE BUT DO NOT REMOVE. THIS IS HERE SO THAT THE DIRECTORY REMAINS diff --git a/changes/build-msi-root b/changes/build-msi-root new file mode 100644 index 0000000000..acbd23d4ff --- /dev/null +++ b/changes/build-msi-root @@ -0,0 +1 @@ +* Fix permissions for building MSI when packaging as root user. Fixes fleetdm/fleet#1424 diff --git a/cmd/package/package.go b/cmd/package/package.go index f226d0767e..3d69626a25 100644 --- a/cmd/package/package.go +++ b/cmd/package/package.go @@ -52,7 +52,7 @@ func main() { &cli.StringFlag{ Name: "version", Usage: "Version for package product", - Value: "0.0.2", + Value: "0.0.3", Destination: &opt.Version, }, &cli.BoolFlag{ diff --git a/pkg/packaging/packaging.go b/pkg/packaging/packaging.go index 9f6887d3c4..93dbdb7797 100644 --- a/pkg/packaging/packaging.go +++ b/pkg/packaging/packaging.go @@ -3,6 +3,7 @@ package packaging import ( "io" + "io/fs" "io/ioutil" "os" "path/filepath" @@ -114,3 +115,17 @@ func writeSecret(opt Options, orbitRoot string) error { return nil } + +func chmodRecursive(path string, perm os.FileMode) error { + return filepath.Walk(path, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return errors.Wrap(err, "walk error") + } + + if err := os.Chmod(path, perm); err != nil { + return errors.Wrap(err, "chmod") + } + + return nil + }) +} \ No newline at end of file diff --git a/pkg/packaging/windows.go b/pkg/packaging/windows.go index cad1f53ee8..f32ac7ab59 100644 --- a/pkg/packaging/windows.go +++ b/pkg/packaging/windows.go @@ -59,6 +59,11 @@ func BuildMSI(opt Options) error { return errors.Wrap(err, "write wix file") } + // Make sure permissions are permissive so that the `wine` user in the Wix Docker container can access files. + if err := chmodRecursive(tmpDir, os.ModePerm); err != nil { + return err + } + if err := wix.Heat(tmpDir); err != nil { return errors.Wrap(err, "package root files") } From ab3047bb39f1e2be331d1ff18b4eb768619033c4 Mon Sep 17 00:00:00 2001 From: Zach Wasserman Date: Wed, 4 Aug 2021 10:04:27 -0700 Subject: [PATCH 110/115] Update usage of os.IsNotExist (#29) Per [godoc](https://pkg.go.dev/os#IsNotExist), this is the preferred method. --- pkg/update/filestore/filestore.go | 4 ++-- pkg/update/update.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/update/filestore/filestore.go b/pkg/update/filestore/filestore.go index 0248795411..b94d7ea250 100644 --- a/pkg/update/filestore/filestore.go +++ b/pkg/update/filestore/filestore.go @@ -54,9 +54,9 @@ func (s *fileStore) GetMeta() (map[string]json.RawMessage, error) { func (s *fileStore) readData() error { stat, err := os.Stat(s.filename) - if err != nil && !os.IsNotExist(err) { + if err != nil && !errors.Is(err, os.ErrNotExist) { return errors.Wrap(err, "stat file store") - } else if os.IsNotExist(err) { + } else if errors.Is(err, os.ErrNotExist) { // initialize empty s.metadata = metadataMap{} return nil diff --git a/pkg/update/update.go b/pkg/update/update.go index 5a9176880d..a992db5fe1 100644 --- a/pkg/update/update.go +++ b/pkg/update/update.go @@ -235,7 +235,7 @@ func (u *Updater) Download(repoPath, localPath string) error { if constant.PlatformName == "windows" { // Remove old file first - if err := os.Rename(localPath, localPath+".old"); err != nil && !os.IsNotExist(err) { + if err := os.Rename(localPath, localPath+".old"); err != nil && !errors.Is(err, os.ErrNotExist) { return errors.Wrap(err, "rename old") } } From 08d96706833adce75dc138614b34626c351f19eb Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 4 Aug 2021 15:41:37 -0300 Subject: [PATCH 111/115] Update .goreleaser.yml --- .goreleaser.yml | 4 ++++ orbit/.goreleaser.yml | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index fcdcf5e37d..863f7c94c5 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,9 @@ project_name: fleet +monorepo: + tag_prefix: fleet- + dir: . + before: hooks: - make deps diff --git a/orbit/.goreleaser.yml b/orbit/.goreleaser.yml index 319f7cae68..ee22771e20 100644 --- a/orbit/.goreleaser.yml +++ b/orbit/.goreleaser.yml @@ -1,10 +1,16 @@ +project_name: orbit + +monorepo: + tag_prefix: orbit- + dir: orbit + before: hooks: - go mod download builds: - id: orbit - dir: ./cmd/orbit/ + dir: ./orbit/cmd/orbit/ binary: orbit env: - CGO_ENABLED=0 @@ -17,10 +23,10 @@ builds: ldflags: - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser hooks: - post: ./tools/build/sign-macos.sh {{ .Path }} + post: ./orbit/tools/build/sign-macos.sh {{ .Path }} - id: orbit-package - dir: ./cmd/package/ + dir: ./orbit/cmd/package/ binary: orbit-package env: - CGO_ENABLED=0 @@ -33,7 +39,7 @@ builds: ldflags: - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}} -X main.builtBy=goreleaser hooks: - post: ./tools/build/sign-macos.sh {{ .Path }} + post: ./orbit/tools/build/sign-macos.sh {{ .Path }} archives: - id: orbit @@ -73,5 +79,5 @@ changelog: release: github: owner: fleetdm - name: orbit + name: fleet draft: true From 9b9407a16dbba817e00277feb25aa324f8622420 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 4 Aug 2021 15:47:03 -0300 Subject: [PATCH 112/115] Update workflows --- ...{goreleaser.yaml => goreleaser-fleet.yaml} | 4 +- .github/workflows/goreleaser-orbit.yaml | 39 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) rename .github/workflows/{goreleaser.yaml => goreleaser-fleet.yaml} (93%) create mode 100644 .github/workflows/goreleaser-orbit.yaml diff --git a/.github/workflows/goreleaser.yaml b/.github/workflows/goreleaser-fleet.yaml similarity index 93% rename from .github/workflows/goreleaser.yaml rename to .github/workflows/goreleaser-fleet.yaml index b99f7a305c..40a4153f19 100644 --- a/.github/workflows/goreleaser.yaml +++ b/.github/workflows/goreleaser-fleet.yaml @@ -3,7 +3,7 @@ name: goreleaser on: push: tags: - - '*' + - 'fleet-*' permissions: contents: write @@ -40,6 +40,6 @@ jobs: with: distribution: goreleaser version: latest - args: release --rm-dist + args: release --rm-dist -f .goreleaser.yml env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/goreleaser-orbit.yaml b/.github/workflows/goreleaser-orbit.yaml new file mode 100644 index 0000000000..52a5cb3a83 --- /dev/null +++ b/.github/workflows/goreleaser-orbit.yaml @@ -0,0 +1,39 @@ +name: goreleaser + +on: + push: + tags: + - 'orbit-*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + environment: Docker Hub + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 # Needed for goreleaser + + - name: Login to Docker Hub + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 # v1.10.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.16.5 + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@ac067437f516133269923265894e77920c3dce18 # v2.6.1 + with: + distribution: goreleaser + version: latest + args: release --rm-dist -f orbit/.goreleaser.yml + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4fe6b2c67dde9ef6286bd6c8bed0263d3795f750 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 4 Aug 2021 15:48:51 -0300 Subject: [PATCH 113/115] No need to login to docker hub for orbit --- .github/workflows/goreleaser-orbit.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/goreleaser-orbit.yaml b/.github/workflows/goreleaser-orbit.yaml index 52a5cb3a83..83920f1809 100644 --- a/.github/workflows/goreleaser-orbit.yaml +++ b/.github/workflows/goreleaser-orbit.yaml @@ -18,12 +18,6 @@ jobs: with: fetch-depth: 0 # Needed for goreleaser - - name: Login to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 # v1.10.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} - - name: Set up Go uses: actions/setup-go@v2 with: From 659066819a3c093eee95d2d4db7fb65124035225 Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Wed, 4 Aug 2021 14:20:49 -0300 Subject: [PATCH 114/115] Fix dead link --- orbit/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orbit/README.md b/orbit/README.md index 6fc1033c0c..69bd457464 100644 --- a/orbit/README.md +++ b/orbit/README.md @@ -192,7 +192,7 @@ Yes! Orbit is licensed under an MIT license and all uses are encouraged. ### How does orbit update osquery? And how do the stable and edge channels get triggered to update osquery on a self hosted Fleet instance? -Orbit uses a configurable update server. We expect that many folks will just use the update server we manage (similar to what Kolide does with Launcher's update server). We are also offering [tooling for self-managing an update server](https://github.com/fleetdm/fleet/blob/master/docs/3-Deployment/4-fleetctl-agent-updates.md) as part of Fleet Basic (the subscription offering). +Orbit uses a configurable update server. We expect that many folks will just use the update server we manage (similar to what Kolide does with Launcher's update server). We are also offering [tooling for self-managing an update server](https://github.com/fleetdm/fleet/blob/main/docs/2-Deploying/4-fleetctl-agent-updates.md) as part of Fleet Basic (the subscription offering). ## Community From b927f7064de8d464893819eabab31a3d37772ddd Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Thu, 5 Aug 2021 13:16:49 -0300 Subject: [PATCH 115/115] Fix workflows --- .../workflows/orbit-golangci-lint.yml | 1 + orbit/.github/workflows/go.yml | 32 ------------------- 2 files changed, 1 insertion(+), 32 deletions(-) rename orbit/.github/workflows/golangci-lint.yml => .github/workflows/orbit-golangci-lint.yml (92%) delete mode 100644 orbit/.github/workflows/go.yml diff --git a/orbit/.github/workflows/golangci-lint.yml b/.github/workflows/orbit-golangci-lint.yml similarity index 92% rename from orbit/.github/workflows/golangci-lint.yml rename to .github/workflows/orbit-golangci-lint.yml index 99a2b6d485..7b4a552985 100644 --- a/orbit/.github/workflows/golangci-lint.yml +++ b/.github/workflows/orbit-golangci-lint.yml @@ -17,3 +17,4 @@ jobs: # specified without patch version: we always use the latest patch # version. version: v1.33 + working-directory: orbit/ diff --git a/orbit/.github/workflows/go.yml b/orbit/.github/workflows/go.yml deleted file mode 100644 index 366e2852eb..0000000000 --- a/orbit/.github/workflows/go.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: build-go - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - - build: - name: Build - runs-on: ubuntu-latest - steps: - - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ^1.15 - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Get dependencies - run: | - go get -v -t -d ./... - - - name: Build - run: go build -v ./... - - - name: Test - run: go test -v ./...