diff --git a/Makefile b/Makefile index 66eb12e..8cd05a2 100644 --- a/Makefile +++ b/Makefile @@ -3,5 +3,11 @@ all: build build: clean cmd/plugin/vault-auth-spire.go GOOS=linux GOARCH=amd64 go build -o vault-auth-spire cmd/plugin/vault-auth-spire.go +test: + go test ./... + +lint: + golint ./... + clean: @rm -f vault-auth-spire diff --git a/cmd/plugin/vault-auth-spire.go b/cmd/plugin/vault-auth-spire.go index a42101b..923c033 100644 --- a/cmd/plugin/vault-auth-spire.go +++ b/cmd/plugin/vault-auth-spire.go @@ -20,10 +20,12 @@ import ( "context" "errors" "flag" + "fmt" + + "github.com/bloomberg/vault-auth-spire/internal/common" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" "github.com/sirupsen/logrus" - "vault-auth-spire/internal/common" "log" "os" @@ -69,7 +71,7 @@ func standardVaultPluginInit() { func BackendFactory(ctx context.Context, backendConfig *logical.BackendConfig) (logical.Backend, error) { settings, err := parseSettings() - if nil != err { + if err != nil { return nil, err } @@ -105,14 +107,23 @@ func BackendFactory(ctx context.Context, backendConfig *logical.BackendConfig) ( spirePlugin.verifier = common.NewSvidVerifier() - if nil != settings.SourceOfTrust.File { + // must add these in reverse order of priority (spire settings will overwrite file settings) + if settings.SourceOfTrust.File != nil { trustSource, err := common.NewFileTrustSource(settings.SourceOfTrust.File.Domains) if err != nil { return nil, errors.New("vault-auth-spire: Failed to initialize file TrustSource - " + err.Error()) } - spirePlugin.verifier.AddTrustSource(&trustSource) - } else { - return nil, errors.New("vault-auth-spire: No verifier found in settings") + spirePlugin.verifier.AddTrustSource(trustSource) + } + if settings.SourceOfTrust.Spire != nil { + trustSource, err := common.NewSpireTrustSource(settings.SourceOfTrust.Spire.SpireEndpointURLs, settings.SourceOfTrust.Spire.LocalBackupPath) + if err != nil { + return nil, errors.New("vault-auth-spire: Failed to initialize spire TrustSource - " + err.Error()) + } + spirePlugin.verifier.AddTrustSource(trustSource) + } + if settings.SourceOfTrust.File == nil && settings.SourceOfTrust.Spire == nil { + return nil, errors.New("vault-auth-spire: No sources of trust in settings") } // Calls standard Vault plugin setup - magic happens here I bet :shrugs: but if it fails then we're gonna @@ -133,11 +144,12 @@ func parseSettings() (*common.Settings, error) { settingsFlags.StringVar(&settingsFilePath, "settings-file", "", "Path to plugin settings") settingsFlags.Parse(os.Args[1:]) - if settings, err := common.ReadSettings(settingsFilePath); err != nil { - return nil, errors.New("vault-auth-spire: Failed to read settings from '" + settingsFilePath + "' - " + err.Error()) - } else { - return settings, nil + settings, err := common.ReadSettings(settingsFilePath) + if err != nil { + return nil, fmt.Errorf("vault-auth-spire: Failed to read settings from %s: %v", settingsFilePath, err) } + + return settings, nil } // spirePlugin is-a framework.Backend as per the embedded unnamed anon field @@ -157,7 +169,7 @@ func (spirePlugin *spirePlugin) pathAuthLogin(_ context.Context, req *logical.Re return nil, logical.ErrInvalidRequest } - spiffeId, err := spirePlugin.verifier.VerifyAndExtractSpiffeId(svid) + spiffeID, err := spirePlugin.verifier.VerifyAndExtractSpiffeID(svid) if err != nil { logrus.Debug("Provided svid could not be verified - " + err.Error()) return nil, logical.ErrPermissionDenied @@ -173,10 +185,10 @@ func (spirePlugin *spirePlugin) pathAuthLogin(_ context.Context, req *logical.Re }, Policies: []string{ //"Trust Bundles: " + strconv.Itoa(len(b.svidWatcher.TrustBundle)), - "Result: We've been verified and I found SPIFFE ID: " + spiffeId, + "Result: We've been verified and I found SPIFFE ID: " + spiffeID, }, Metadata: map[string]string{ - "spiffeId": spiffeId, + "spiffeId": spiffeID, }, LeaseOptions: logical.LeaseOptions{ Renewable: false, diff --git a/go.mod b/go.mod index f8cd07c..1f604ac 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,26 @@ -module vault-auth-spire +module github.com/bloomberg/vault-auth-spire go 1.12 require ( - cloud.google.com/go v0.47.0 // indirect - cloud.google.com/go/bigquery v1.2.0 // indirect - cloud.google.com/go/storage v1.1.2 // indirect - github.com/creack/pty v1.1.9 // indirect github.com/go-test/deep v1.0.3 // indirect github.com/gogo/protobuf v1.3.1 // indirect - github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect - github.com/google/go-cmp v0.3.1 // indirect - github.com/google/pprof v0.0.0-20191028172815-5e965273ee43 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hashicorp/vault/api v1.0.4 github.com/hashicorp/vault/sdk v0.1.13 - github.com/jstemmer/go-junit-report v0.9.1 // indirect - github.com/kr/pty v1.1.8 // indirect github.com/natefinch/lumberjack v2.0.0+incompatible - github.com/rogpeppe/go-internal v1.5.0 // indirect + github.com/prometheus/common v0.4.0 github.com/sirupsen/logrus v1.2.0 + github.com/spf13/afero v1.1.2 github.com/spf13/viper v1.4.0 github.com/spiffe/go-spiffe v0.0.0-20190922191205-018e7197ed1c - github.com/stretchr/objx v0.2.0 // indirect - github.com/stretchr/testify v1.4.0 // indirect - go.opencensus.io v0.22.1 // indirect + github.com/stretchr/testify v1.4.0 golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf // indirect - golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 // indirect - golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect - golang.org/x/mobile v0.0.0-20191025110607-73ccc5ba0426 // indirect golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 // indirect - golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c // indirect + golang.org/x/text v0.3.2 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect - golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab // indirect - golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect - google.golang.org/appengine v1.6.5 // indirect + google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 // indirect google.golang.org/grpc v1.24.0 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index cefaa2e..9e9c29b 100644 --- a/go.sum +++ b/go.sum @@ -1,23 +1,10 @@ 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 v0.47.0/go.mod h1:5p3Ky/7f3N10VBkhuR5LFtddroTiMyjZV/Kj5qOQFxU= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.2.0/go.mod h1:Cqg1qaK3wRdys8sKlow0jIBVFwSTiHoFx5um4ujCpyE= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -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= -cloud.google.com/go/storage v1.1.2/go.mod h1:/03MkR5FWjF0OpcKpdJ4RgWybEaYAr2boHXq5RDlxbw= -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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 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= @@ -33,8 +20,6 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc 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/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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= @@ -46,7 +31,6 @@ github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -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-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -59,15 +43,12 @@ github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a 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/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= 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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9/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 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -75,19 +56,9 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -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 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= 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/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/pprof v0.0.0-20191028172815-5e965273ee43/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -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/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= 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= @@ -132,8 +103,6 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -144,7 +113,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB 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/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= 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/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= @@ -184,13 +152,12 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf 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 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/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= 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.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= @@ -208,13 +175,10 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spiffe/go-spiffe v0.0.0-20190820222348-6adcf1eecbcc h1:YeGvOZLHZxE8nrxPGDNH1LGv8zzkAIDfIRgy256rotk= -github.com/spiffe/go-spiffe v0.0.0-20190820222348-6adcf1eecbcc/go.mod h1:HyNeJnVYkDyQgB2qcSPxVYkAA2F3lQu51bDxNpFcKxY= github.com/spiffe/go-spiffe v0.0.0-20190922191205-018e7197ed1c h1:wpwh25WjvKF8/+N+wMy1u9nMiOXfw5sqpmL5ZSAFIWU= github.com/spiffe/go-spiffe v0.0.0-20190922191205-018e7197ed1c/go.mod h1:HyNeJnVYkDyQgB2qcSPxVYkAA2F3lQu51bDxNpFcKxY= 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/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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= @@ -224,72 +188,36 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr 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= 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.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= 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-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -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 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss= golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= -golang.org/x/exp v0.0.0-20191014171548-69215a2ee97e/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191024150812-c286b889502e/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -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/image v0.0.0-20191009234506-e7c1f5e7dbb8/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/mobile v0.0.0-20191025110607-73ccc5ba0426/go.mod h1:p895TfNkDgPEmEQrNiOtIl3j98d/tGU95djDj7NfyjQ= -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/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-20181114220301-adae6a3d119a/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -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-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271 h1:N66aaryRB3Ax92gH0v3hp1QYZ3zWWCCUR/j8Ifh45Ss= golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 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/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= @@ -297,25 +225,16 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e h1:nFYrTHrdrAOpShe27kaFHjsqYSEQ0KWqdWLu3xuZJts= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/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-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c h1:S/FtSvpNLtFBgjTqcKsRpsa6aVsI6iztaz1bQd9BJwE= golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.1-0.20181227161524-e6919f6577db h1:6/JqlYfC1CCaLnGceQTI+sDGhC9UBSPAsBqI0Gun6kU= golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -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/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= @@ -326,68 +245,29 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/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-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-20190524140312-2c0ae7006135/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-20190909214602-067311248421/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-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010171213-8abd42400456/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-20191022210528-83d82311fd1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191028194131-d78a1f2664a0/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191030062658-86caa796c7ab/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -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= -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.11.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -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/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/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 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= -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-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6 h1:UXl+Zk3jqqcbEVV7ace5lrt4YdA4tXiz3f/KbmD29Vo= google.golang.org/genproto v0.0.0-20191028173616-919d9bdd9fe6/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= 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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.0 h1:J0UbZOIrCAl+fpTOf8YLs4dJo8L/owV4LYVtAXQoPkw= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0 h1:vb/1TCsVn3DcJlQ0Gs1yB1pKI6Do2/QNwxdKqmc/b0s= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +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/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -400,8 +280,4 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/common/common.go b/internal/common/common.go new file mode 100644 index 0000000..3dc4e59 --- /dev/null +++ b/internal/common/common.go @@ -0,0 +1,5 @@ +package common + +import "github.com/spf13/afero" + +var appFS = afero.NewOsFs() diff --git a/internal/common/common_test.go b/internal/common/common_test.go new file mode 100644 index 0000000..2326731 --- /dev/null +++ b/internal/common/common_test.go @@ -0,0 +1,67 @@ +package common + +const ( + leafCert = ` +-----BEGIN CERTIFICATE----- +MIIE1DCCArygAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoMDnRlc3QxLmFjbWUuY29tMRcwFQYDVQQDDA5JbnRlcm1lZGlhZXRD +QTAeFw0xNzA3MTkxNjUwMjBaFw0xNzA3MjkxNjUwMjBaMDUxCzAJBgNVBAYTAlVT +MRcwFQYDVQQKDA50ZXN0MS5hY21lLmNvbTENMAsGA1UEAwwEYmxvZzCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKm8P47lABp4+rz2nN+QYrxedbaFVWoF +FuoSkqcHsafMwbMrN+kI6wJVtlbwviDvxWFJ92q0H71QNFybTsmof3KUN/kYCp7P ++LKhBrN0ttWI5q6v5eDrjN0VdtVdnlZOYmJFbvETOgfK/qXKNRRM8HYW0tdqrtEw +CR5dIu53xVUSViBdwXpuy2c5W2mFn1gxTpdW+3hbZsL1pHrU9qPWLtTgl/KY8kjs +I7KW1cIcinE4SJomhB5L/4emhxKGY+kEa2+fN9IPjjvKSMOw9kiBKk1GHZcIY5EA +O3TIfUk3fysPzi5qA0su/bNtPQy1uXgXS10xUlV7pqRPvHjiNzgFkXUCAwEAAaOB +4zCB4DAJBgNVHRMEAjAAMB0GA1UdDgQWBBRVQ91jSOONzVr1VGBdJOlPN+3XxTBg +BgNVHSMEWTBXgBQ13bfx50rDZO3y2CZdHPgleFUEoKE7pDkwNzELMAkGA1UEBhMC +VVMxFzAVBgNVBAoMDnRlc3QxLmFjbWUuY29tMQ8wDQYDVQQDDAZSb290Q0GCAhAA +MA4GA1UdDwEB/wQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAtBgNVHREEJjAk +hiJzcGlmZmU6Ly9kZXYuYWNtZS5jb20vcGF0aC9zZXJ2aWNlMA0GCSqGSIb3DQEB +CwUAA4ICAQBp2+rtUxt1VmNM/vi6PwoSoYzWFmQ2nc4OM7bsOG4uppU54wRYZ+T7 +c42EcrpyBgWn+rWHT1Hi6SNcmloKHydaUTZ4pq3IlKKnBNqwivU5BzIxYLDrhR/U +wd9s1tgmLvADqkQa1XjjSFn5Auoj1R640ry4qpw8IOusdm6wVhru4ssRnHX4E2uR +jQe7b3ws38aZhjtL78Ip0BB4yPxWJRp/WmEoT33QP+cZhA4IYWECxNODr6DSJeq2 +VNu/6JACGrNfM2Sjt4Wxz+nIa3cKDNCA6PR8StTUTcoQ6ZBzpn+n/Q1xSRIOJz6N +hgfkyb9O7HAMdAP+TxehjqG3gh5Ky2DgYMCIZOztVzsuOb1DGJe/kGUKeRJLl2/O +QwkctwUOcVIxckNu6OvclriFzvoXObqO77XeCI2V1Vef0wGTWlWNOdbFa4708Y7f +5UdwInYQUi87RFDnc1SDU4Jrsv4KzZiv9FCfDg8pCBIdWpWT7DAuI0d7i7PZ+iFt +ZZ6sb/YDkyiDXU4ar/dja0FDE2r7jsN9D+FfW49+iDvXr4ELQyhZpW3Zr1Ojwm58 +CJzjZwbRYiVwPBRsKmiYfO1E7esvw3CmjK5chfz8c40f6/APDro9ZmYNBRv2CnJy +t/DtcM/GpAhBbLP9Tk7kPB41v5fRIxVDo50Iz/qvkr37pQ4RsejSFg== +-----END CERTIFICATE-----` + intermediateCert = ` +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwNzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoMDnRlc3QxLmFjbWUuY29tMQ8wDQYDVQQDDAZSb290Q0EwHhcNMTcw +NzE5MTY1MDIwWhcNMTcxMDI3MTY1MDIwWjA/MQswCQYDVQQGEwJVUzEXMBUGA1UE +CgwOdGVzdDEuYWNtZS5jb20xFzAVBgNVBAMMDkludGVybWVkaWFldENBMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAph7QhbUKEjMWu2R/WXIc8RR0ymCL +njJTm0D5duTe7V2hklLhCo1KnZAjvDiDX9r85UfEja5MYItHmFF4HOZjSG6nY3Yg +Mm5hdJM7Jmv9NJR8DJInROabfRcaPdugs2UQ41jCEygIoWiZ9+yVlZ21MNW0yQdI +JHUNndQfXpS7dBdKw6fUqzZgpdzo86mAapZDIPL7gXv6MW8JhbvQCm+bg7SRIJOD +t/a1T0nHPNuwxdDWjGcmJEQRknffL8pheDlW9sMAd/4BtIeaWUEb3JjdDoaJ9SWU +tCgGRZOMnmry8npJnssyoLUtIPuk8949REOUB15nT94EhTtb1BMdiuD8P8HOHWC6 +mcxpJCsKlCFmOQpES6WROqjckQJ0f/xPOdKAdI9W0Eg3TRtibV9XTfTvv8SPug9/ +6FnkdpwF5xlJ/XcuW8GtpHUZNQ0NyxjUh2rQRAbwdTMeCvhx5fPHpT2kc6PIlzLw +h4Pt0Xvc1cNt2iJOVDqs75HvvUe4RYTfdqlK5385u/s2cxQrLuB4owJrTyrqc3yM +L/0h5JXr9P+T+axrd5WQWz2ngiaimli2vxZTR++RfBnyCgQGTiY+9UUOYYgHh6hJ +CGUPY77DsKuTfIXYlra+c65FKFAcZrC4vt1CLtBqW2mBy7U868c0L9PZ1g3+WGvA +FmnZA6MgUKQE0i0CAwEAAaOBlTCBkjAdBgNVHQ4EFgQUNd238edKw2Tt8tgmXRz4 +JXhVBKAwHwYDVR0jBBgwFoAUUeBRd0yew4JtInksRTlbz71YwtEwDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwLwYDVR0eAQH/BCUwI6AhMA+GDS5kZXYu +YWNtZS5jb20wDoYMZGV2LmFjbWUuY29tMA0GCSqGSIb3DQEBCwUAA4ICAQBLljbI +ekm5/uhFbc/aCAlomwGkXFvyMXx7eD7Pimzn4H31nYvQ5ha2M0536JC/mH1xi7nK +OOMuSBAqjpALoRk4+3O5s6r9BN8KKhcI4jDKHqOSBe38K+Ad06B52yxYyL6YmJwk +Zlazf3KvExzUWS0t4ehNuI2HJvvwEitMpOF3hhwAYk3v/x2YBtpglH+yZC4Sfoma +ItjFWeD+DA0bVAMJiErz8Pq91avnC8SPpPXiPJVOaBhaNc8po6x6cwSqY6RnI2/K +0kUWXXH65Pz0JYru53ALzy4ouwJItcgMvzZPGVaojxEbGDrjXEkWIGresFrw1Ijr +IyrQUqWa9wW6ik+IQOb6m3FZYB8jMO7nhop9Ywm9uoSmFRg6RsP2AWHBMYP7lZqw +fx3HjrAvc3ycIZ2tSPkdLd5n8YuL31CVpa9aGwT5dYzIVd/eFUrCUIGV2j8XHgkL +gMPr8JhNPAG0B4rRpEXmK3HHybo3s0M8i80Lit98xzupNpng97xKT7jJBSinNTdt +/2uU7diHQM7aPNmNG+Wu3GXVt/MZuDMSFrh9AHl0A/Y4mNu6KKqRMJuvsfy/j1DD +fDGmAkjHrspiorTruphHk+cymJfjAGqZ0l6il4Wi5w4R5jrxnJMhkxbjr/PG5xCS ++ZKPPNZbpPIY54oQ2bHkuaQgzJ7us4ZW7gxgbw== +-----END CERTIFICATE-----` + certChain = intermediateCert + leafCert +) diff --git a/internal/common/filetrustsource.go b/internal/common/filetrustsource.go index 258412f..745c65b 100644 --- a/internal/common/filetrustsource.go +++ b/internal/common/filetrustsource.go @@ -19,8 +19,10 @@ package common import ( "crypto/x509" "errors" - "github.com/sirupsen/logrus" + "fmt" "io/ioutil" + + "github.com/sirupsen/logrus" ) // FileTrustSource provides support for PEM-file based trust sources. This trust source @@ -37,17 +39,17 @@ type FileTrustSource struct { // result in an error. Failure to parse a certificate from a PEM file will result in // that certificate being ignored. If no certificates are loaded from a PEM file then // an INFO message will be added to the log. -func NewFileTrustSource(domainPaths map[string][]string) (FileTrustSource, error) { +func NewFileTrustSource(domainPaths map[string][]string) (*FileTrustSource, error) { source := FileTrustSource{ domainPaths: domainPaths, domainCertificates: make(map[string][]*x509.Certificate, 0), } if err := source.loadCertificates(); err != nil { - return source, err + return &source, err } - return source, nil + return &source, nil } // TrustedCertificates returns our current maps of domains to certificates. This is a @@ -59,24 +61,42 @@ func (source *FileTrustSource) TrustedCertificates() map[string][]*x509.Certific // For each domain/file mapping found in source.domainPaths, load the PEM and read all // certificates from the file. func (source *FileTrustSource) loadCertificates() error { - for domain, paths := range source.domainPaths { - domainCertificates := make([]*x509.Certificate, 0) + for domain := range source.domainPaths { + err := source.loadDomain(domain) + if err != nil { + return err + } + } - for _, path := range paths { - data, err := ioutil.ReadFile(path) - if err != nil { - return errors.New("Failed to load certificates for domain " + domain + " from file " + path + " - " + err.Error()) - } + return nil +} + +func (source *FileTrustSource) loadDomain(domain string) error { + paths := source.domainPaths[domain] + domainCertificates := make([]*x509.Certificate, 0) - certificates := ExtractCertificatesFromPem(data) - if len(certificates) == 0 { - logrus.Info("Did not load any certificates for domain " + domain + " from file " + path) - } - domainCertificates = append(domainCertificates, certificates...) + for _, path := range paths { + file, err := appFS.Open(path) + if err != nil { + return fmt.Errorf("Could not open file %s while loading certificates: %v", path, err) + } + defer file.Close() + data, err := ioutil.ReadAll(file) + if err != nil { + return errors.New("Failed to load certificates for domain " + domain + " from file " + path + ": " + err.Error()) } - source.domainCertificates[domain] = domainCertificates + certificates := ExtractCertificatesFromPem(data) + if len(certificates) == 0 { + logrus.WithFields(logrus.Fields{ + "domain": domain, + "path": path, + }).Info("Did not load any certificates from file") + } + domainCertificates = append(domainCertificates, certificates...) } + source.domainCertificates[domain] = domainCertificates + return nil } diff --git a/internal/common/filetrustsource_test.go b/internal/common/filetrustsource_test.go new file mode 100644 index 0000000..fafb114 --- /dev/null +++ b/internal/common/filetrustsource_test.go @@ -0,0 +1,74 @@ +package common + +import ( + "testing" + + "github.com/spf13/afero" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSingleCertificate(t *testing.T) { + appFS = afero.NewMemMapFs() + + afero.WriteFile(appFS, "leaf.pem", []byte(leafCert), 600) + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"leaf.pem"}, + }) + require.NoError(t, err) + + exampleDomain := source.TrustedCertificates()["spiffe://example.org"] + require.Len(t, exampleDomain, 1) + + assert.Equal(t, "US", exampleDomain[0].Subject.Country[0]) + assert.Equal(t, "test1.acme.com", exampleDomain[0].Subject.Organization[0]) + assert.Equal(t, "blog", exampleDomain[0].Subject.CommonName) +} + +func TestDoubleCertificate(t *testing.T) { + appFS = afero.NewMemMapFs() + + afero.WriteFile(appFS, "chain.pem", []byte(certChain), 600) + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"chain.pem"}, + }) + require.NoError(t, err) + + exampleDomain := source.TrustedCertificates()["spiffe://example.org"] + require.Len(t, exampleDomain, 2) + + assert := assert.New(t) + + assert.Equal("US", exampleDomain[0].Subject.Country[0]) + assert.Equal("test1.acme.com", exampleDomain[0].Subject.Organization[0]) + assert.Equal("IntermediaetCA", exampleDomain[0].Subject.CommonName) + + assert.Equal("US", exampleDomain[1].Subject.Country[0]) + assert.Equal("test1.acme.com", exampleDomain[1].Subject.Organization[0]) + assert.Equal("blog", exampleDomain[1].Subject.CommonName) +} + +func TestBadFile(t *testing.T) { + appFS = afero.NewMemMapFs() + + _, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"chain.pem"}, + }) + require.Error(t, err) +} + +func TestEmptyCerts(t *testing.T) { + appFS = afero.NewMemMapFs() + + afero.WriteFile(appFS, "chain.pem", []byte(""), 600) + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"chain.pem"}, + }) + require.NoError(t, err) + + exampleDomain := source.TrustedCertificates()["spiffe://example.org"] + require.Len(t, exampleDomain, 0) +} diff --git a/internal/common/logger.go b/internal/common/logger.go index 1b4ccae..977eacf 100644 --- a/internal/common/logger.go +++ b/internal/common/logger.go @@ -54,6 +54,7 @@ func (u utcFormatter) Format(e *logrus.Entry) ([]byte, error) { return u.formatter.Format(e) } +// InitializeLogger creates a new logger with the specified settings func InitializeLogger(settings *Settings) error { logDirectory := filepath.Dir(settings.Log.Filename) if err := os.MkdirAll(logDirectory, 0755); err != nil { diff --git a/internal/common/settings.go b/internal/common/settings.go index e9a2596..75e703a 100644 --- a/internal/common/settings.go +++ b/internal/common/settings.go @@ -21,19 +21,30 @@ import ( "github.com/spf13/viper" ) +// Settings is the root set of settings for root plugin type Settings struct { Log *LogSettings SourceOfTrust *SourceOfTrustSettings } +// SourceOfTrustSettings holds settings for all source of truth providers type SourceOfTrustSettings struct { - File *FileTrustSourceSettings + File *FileTrustSourceSettings + Spire *SpireTrustSourceSettings } +// FileTrustSourceSettings holds a mapping of domains to certificate paths type FileTrustSourceSettings struct { Domains map[string][]string } +// SpireTrustSourceSettings holds spire endpoint locations and a path to store certs from Spire in +type SpireTrustSourceSettings struct { + SpireEndpointURLs map[string]string + LocalBackupPath string +} + +// LogSettings holds relevant logging settings type LogSettings struct { Filename string Level string @@ -43,10 +54,7 @@ type LogSettings struct { Compress bool } -func wrapError(err error) error { - return errors.New("parse-settings: " + err.Error()) -} - +// ReadSettings reads settings from JSON into config objects using Viper func ReadSettings(fromPath string) (*Settings, error) { settings := new(Settings) @@ -56,17 +64,17 @@ func ReadSettings(fromPath string) (*Settings, error) { // Load the config from disk at sourcePath viper.SetConfigFile(fromPath) if err = viper.ReadInConfig(); err != nil { - return nil, wrapError(err) + return nil, err } // Read logging settings if settings.Log, err = readLogSettings(); err != nil { - return nil, wrapError(err) + return nil, err } // Read our source of trust settings if settings.SourceOfTrust, err = readSourceOfTrustSettings(); err != nil { - return nil, wrapError(err) + return nil, err } return settings, nil @@ -112,12 +120,11 @@ func readSourceOfTrustSettings() (*SourceOfTrustSettings, error) { } } - // TODO: Add implementation for Spire being the source of trust - //if(viper.IsSet("trustsource.spire")){ - // if trustSettings.File, err = readSpireSourceOfTrustSettings(); err != nil { - // return nil, err - // } - //} + if viper.IsSet("trustsource.spire") { + if sourceOfTrust.Spire, err = readSpireSourceOfTrustSettings(); err != nil { + return nil, err + } + } return sourceOfTrust, nil } @@ -132,3 +139,21 @@ func readFileSourceOfTrustSettings() (*FileTrustSourceSettings, error) { return fileSettings, nil } + +func readSpireSourceOfTrustSettings() (*SpireTrustSourceSettings, error) { + if !viper.IsSet("trustsource.spire.domains") { + return nil, errors.New("trustsource.spire.domains is required but not found") + } + + viper.SetDefault("trustsource.spire.backupPath", "/var/run/spire/certs/") + viper.SetDefault("trustsource.spire.storeEnabled", true) + spireSettings := &SpireTrustSourceSettings{ + SpireEndpointURLs: viper.GetStringMapString("trustsource.spire.domains"), + LocalBackupPath: viper.GetString("trustsource.spire.backupPath"), + } + if !viper.GetBool("trustsource.spire.storeEnabled") { + spireSettings.LocalBackupPath = "" + } + + return spireSettings, nil +} diff --git a/internal/common/spiretrustsource.go b/internal/common/spiretrustsource.go new file mode 100644 index 0000000..8a1ac31 --- /dev/null +++ b/internal/common/spiretrustsource.go @@ -0,0 +1,215 @@ +package common + +import ( + "crypto/x509" + "encoding/pem" + "fmt" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "github.com/sirupsen/logrus" + "github.com/spiffe/go-spiffe/workload" +) + +// SpireLoadState represents the current state of a Spire connection +type SpireLoadState int + +const ( + Pending SpireLoadState = iota + Loaded + LoadedFromBackup + Failed +) + +// SpireEndpoint represents a single trust domain and its associated spire server connection +type SpireEndpoint struct { + domain string + loadState SpireLoadState + spireURL string + + client *workload.X509SVIDClient +} + +// SpireTrustSource holds all necessary information to connect to a spire instance and store its certificates +type SpireTrustSource struct { + spireEndpoints map[string]*SpireEndpoint + + localBackupDir string + + updateChan chan struct{} + updateTimeout time.Duration + + domainCertificates map[string][]*x509.Certificate + testing bool +} + +type workloadWatcher struct { + domain string + source *SpireTrustSource + localStoragePath string +} + +// TrustedCertificates fulfills the TrustSource interface +func (s *SpireTrustSource) TrustedCertificates() map[string][]*x509.Certificate { + return s.domainCertificates +} + +// NewSpireTrustSource creates a new trust source with connectivity to one or more spire instances. +func NewSpireTrustSource(spireEndpointURLs map[string]string, localBackupDir string) (*SpireTrustSource, error) { + source := &SpireTrustSource{ + spireEndpoints: make(map[string]*SpireEndpoint, 0), + localBackupDir: localBackupDir, + domainCertificates: make(map[string][]*x509.Certificate, 0), + updateChan: make(chan struct{}, 0), + updateTimeout: 5 * time.Second, + } + + re := regexp.MustCompile(`^spiffe://(\S+)$`) + for trustDomain, spireURL := range spireEndpointURLs { + localStoragePath := "" + if localBackupDir != "" { + matches := re.FindStringSubmatch(trustDomain) + if len(matches) < 2 { + return nil, fmt.Errorf("expected domain of form spiffe:// but got %s", trustDomain) + } + domain := matches[1] + if strings.Contains(domain, "/") { + return nil, fmt.Errorf("expected domain without slash but got %s", domain) + } + localStoragePath = filepath.Join(localBackupDir, domain+".pem") + } + + client, err := workload.NewX509SVIDClient( + &workloadWatcher{ + domain: trustDomain, + source: source, + localStoragePath: localStoragePath, + }, + workload.WithAddr(spireURL), + ) + if err != nil { + return nil, fmt.Errorf("failed to construct a new NewX509SVIDClient for %s: %v", spireURL, err) + } + + source.spireEndpoints[trustDomain] = &SpireEndpoint{ + domain: trustDomain, + loadState: Pending, + spireURL: spireURL, + client: client, + } + } + + for _, spireEndpoint := range source.spireEndpoints { + if err := spireEndpoint.client.Start(); err != nil { + return nil, fmt.Errorf("failed to start NewX509SVIDClient for domain %s: %v", spireEndpoint.domain, err) + } + } + + return source, nil +} + +// NewSpireTestSource creates a new spire trust source with the test flag on. +func NewSpireTestSource(spireEndpointURLs map[string]string, localBackupDir string) (*SpireTrustSource, error) { + ts, err := NewSpireTrustSource(spireEndpointURLs, localBackupDir) + if err != nil { + return nil, err + } + ts.testing = true + return ts, nil +} + +// Stop stops all spire clients +func (s *SpireTrustSource) Stop() error { + errs := make([]string, 0) + for _, spireEndpoint := range s.spireEndpoints { + if err := spireEndpoint.client.Stop(); err != nil { + errs = append(errs, fmt.Sprintf("domain %s: %v", spireEndpoint.domain, err)) + } + } + + if len(errs) != 0 { + return fmt.Errorf("failed to stop NewX509SVIDClients: (%s)", strings.Join(errs, "),(")) + } + + return nil +} + +func (w *workloadWatcher) UpdateX509SVIDs(svids *workload.X509SVIDs) { + certs := svids.Default().TrustBundle + w.source.domainCertificates[w.domain] = certs + w.source.spireEndpoints[w.domain].loadState = Loaded + + if w.localStoragePath != "" { + builder := strings.Builder{} + for _, cert := range certs { + block := &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Raw, + } + builder.Write(pem.EncodeToMemory(block)) + } + file, err := appFS.OpenFile(w.localStoragePath, os.O_WRONLY|os.O_CREATE, 0600) + if err != nil { + logrus.WithFields(logrus.Fields{ + "domain": w.domain, + "path": w.localStoragePath, + }).Warnf("could not open backup file for trust domain: %v", err) + } else { + defer file.Close() + _, err = file.WriteString(builder.String()) + if err != nil { + logrus.WithFields(logrus.Fields{ + "domain": w.domain, + "path": w.localStoragePath, + }).Warnf("could not write to backup file for trust domain: %v", err) + } + } + } + + if w.source.testing { + select { + case w.source.updateChan <- struct{}{}: + case <-time.After(w.source.updateTimeout): + } + } +} + +func (w *workloadWatcher) OnError(err error) { + if w.source.spireEndpoints[w.domain].loadState == Pending { + if w.localStoragePath != "" { + domainPaths := map[string][]string{ + w.domain: []string{w.localStoragePath}, + } + + if fileTrustSource, err := NewFileTrustSource(domainPaths); err != nil { + logrus.WithFields(logrus.Fields{ + "domain": w.domain, + }).Warnf("could not load backup certs for from disk: %v", err) + w.source.spireEndpoints[w.domain].loadState = Failed + } else { + w.source.domainCertificates[w.domain] = fileTrustSource.TrustedCertificates()[w.domain] + w.source.spireEndpoints[w.domain].loadState = LoadedFromBackup + logrus.WithFields(logrus.Fields{ + "domain": w.domain, + }).Infof("loaded backup certs from disk") + } + } else { + w.source.spireEndpoints[w.domain].loadState = Failed + logrus.WithFields(logrus.Fields{ + "domain": w.domain, + }).Warn("could not connect to spire server and local storage disabled") + } + } else { + // if the state was already Loaded, LoadedFromBackup, or Failed then don't do anything + } + + if w.source.testing { + select { + case w.source.updateChan <- struct{}{}: + case <-time.After(w.source.updateTimeout): + } + } +} diff --git a/internal/common/spiretrustsource_test.go b/internal/common/spiretrustsource_test.go new file mode 100644 index 0000000..1687fa8 --- /dev/null +++ b/internal/common/spiretrustsource_test.go @@ -0,0 +1,155 @@ +package common + +import ( + "crypto" + "crypto/x509" + "testing" + "time" + + "github.com/spf13/afero" + "github.com/spiffe/go-spiffe/spiffetest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + updateTimeout = 5 * time.Second +) + +// makeX509SVIDResponse is a convenience function for generating X509 responses +func setX509SVIDResponse(api *spiffetest.WorkloadAPI, ca *spiffetest.CA, svid []*x509.Certificate, key crypto.Signer) { + response := &spiffetest.X509SVIDResponse{ + Bundle: ca.Roots(), + SVIDs: []spiffetest.X509SVID{ + { + CertChain: svid, + Key: key, + }, + }, + } + api.SetX509SVIDResponse(response) +} + +func TestInitialLoad(t *testing.T) { + appFS = afero.NewMemMapFs() + + afero.WriteFile(appFS, "certs/example.org.pem", []byte(leafCert), 600) + + workloadAPI := spiffetest.NewWorkloadAPI(t, nil) + defer workloadAPI.Stop() + + source, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org": workloadAPI.Addr(), + }, "certs/") + require.NoError(t, err) + defer source.Stop() + + source.waitForUpdate(t) + + certs := source.TrustedCertificates()["spiffe://example.org"] + require.Len(t, certs, 1) + assert.Equal(t, "US", certs[0].Subject.Country[0]) + assert.Equal(t, "test1.acme.com", certs[0].Subject.Organization[0]) + assert.Equal(t, "blog", certs[0].Subject.CommonName) +} + +func TestInvalidURI(t *testing.T) { + _, err := NewSpireTestSource(map[string]string{ + "spirffe://example.org": "", + }, "certs/") + require.Error(t, err) +} + +func TestInvalidDomain(t *testing.T) { + _, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org/test": "", + }, "certs/") + require.Error(t, err) +} + +func TestWriteCerts(t *testing.T) { + appFS = afero.NewMemMapFs() + + workloadAPI := spiffetest.NewWorkloadAPI(t, nil) + defer workloadAPI.Stop() + + ca := spiffetest.NewCA(t) + svidFoo, keyFoo := ca.CreateX509SVID("spiffe://example.org/foo") + + setX509SVIDResponse(workloadAPI, ca, svidFoo, keyFoo) + + source, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org": workloadAPI.Addr(), + }, "certs/") + require.NoError(t, err) + + source.waitForUpdate(t) + source.Stop() + + dummyWorkloadAPI := spiffetest.NewWorkloadAPI(t, nil) + defer dummyWorkloadAPI.Stop() + + newSource, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org": dummyWorkloadAPI.Addr(), + }, "certs/") + newSource.waitForUpdate(t) + assert.Equal(t, ca.Roots(), newSource.TrustedCertificates()["spiffe://example.org"]) +} + +func TestSpireOverwrite(t *testing.T) { + appFS = afero.NewMemMapFs() + + afero.WriteFile(appFS, "certs/example.org.pem", []byte(leafCert), 600) + + workloadAPI := spiffetest.NewWorkloadAPI(t, nil) + defer workloadAPI.Stop() + + ca := spiffetest.NewCA(t) + svidFoo, keyFoo := ca.CreateX509SVID("spiffe://example.org/foo") + + setX509SVIDResponse(workloadAPI, ca, svidFoo, keyFoo) + + source, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org": workloadAPI.Addr(), + }, "certs/") + require.NoError(t, err) + defer source.Stop() + + source.waitForUpdate(t) + assert.Equal(t, ca.Roots(), source.TrustedCertificates()["spiffe://example.org"]) +} + +func TestSpireRotation(t *testing.T) { + appFS = afero.NewMemMapFs() + + workloadAPI := spiffetest.NewWorkloadAPI(t, nil) + defer workloadAPI.Stop() + + ca := spiffetest.NewCA(t) + svidFoo, keyFoo := ca.CreateX509SVID("spiffe://example.org/foo") + setX509SVIDResponse(workloadAPI, ca, svidFoo, keyFoo) + + source, err := NewSpireTestSource(map[string]string{ + "spiffe://example.org": workloadAPI.Addr(), + }, "") + require.NoError(t, err) + defer source.Stop() + + source.waitForUpdate(t) + assert.Equal(t, ca.Roots(), source.TrustedCertificates()["spiffe://example.org"]) + + caRot := spiffetest.NewCA(t) + svidFooRot, keyFooRot := ca.CreateX509SVID("spiffe://example.org/foo") + setX509SVIDResponse(workloadAPI, caRot, svidFooRot, keyFooRot) + + source.waitForUpdate(t) + assert.Equal(t, caRot.Roots(), source.TrustedCertificates()["spiffe://example.org"]) +} + +func (s *SpireTrustSource) waitForUpdate(t *testing.T) { + select { + case <-s.updateChan: + case <-time.After(updateTimeout): + require.Fail(t, "Timeout exceeding waiting for updates.") + } +} diff --git a/internal/common/svidverifier.go b/internal/common/svidverifier.go index 28db45e..ea4bd14 100644 --- a/internal/common/svidverifier.go +++ b/internal/common/svidverifier.go @@ -31,6 +31,7 @@ type SvidVerifier struct { trustSources []TrustSource } +// NewSvidVerifier creates a new SVID verifier func NewSvidVerifier() SvidVerifier { return SvidVerifier{ trustSources: make([]TrustSource, 0), @@ -42,26 +43,26 @@ func (verifier *SvidVerifier) AddTrustSource(source TrustSource) { verifier.trustSources = append(verifier.trustSources, source) } -// VerifyAndExtractSpiffeId will take the provided SVID and verify its source against any of the known +// VerifyAndExtractSpiffeID will take the provided SVID and verify its source against any of the known // sources of trust. If the SVID was generated using any of the known sources of trust and adheres to // all required SPIFFE requirements for an SVID then the SVID will be considered verified and the // SPIFFE ID of the SVID will be returned. If the SVID cannot be verified then an error will // be returned. -func (verifier *SvidVerifier) VerifyAndExtractSpiffeId(svid string) (string, error) { +func (verifier *SvidVerifier) VerifyAndExtractSpiffeID(svid string) (string, error) { logrus.Debug("Beginning SVID verification") // right now we only support X509 verification - spiffeId, err := verifier.verifyAndExtractSpiffeIdFromX509(svid) + spiffeID, err := verifier.verifyAndExtractSpiffeIDFromX509(svid) if err != nil { return "", err } // SPIFFE validation requirements - if err := spiffe.ValidateID(spiffeId, spiffe.AllowAnyTrustDomainWorkload()); err != nil { + if err := spiffe.ValidateID(spiffeID, spiffe.AllowAnyTrustDomainWorkload()); err != nil { return "", errors.New("SVID is invalid - invalid SPIFFE ID found - " + err.Error()) } - return spiffeId, nil + return spiffeID, nil } // VerifyAndExtractSpiffeIdFromX509 will take the provided X509-SVID and verify its source against any @@ -71,7 +72,7 @@ func (verifier *SvidVerifier) VerifyAndExtractSpiffeId(svid string) (string, err // be returned. The SPIFFE ID of an X509-SVID is defined as the first SAN URI found in the first certificate // of the SVID. That is, if it contains multiple certificates then the first is the one containing the // 'caller' SPIFFE ID. -func (verifier *SvidVerifier) verifyAndExtractSpiffeIdFromX509(svid string) (string, error) { +func (verifier *SvidVerifier) verifyAndExtractSpiffeIDFromX509(svid string) (string, error) { logrus.Debug("Beginning SVID X509 verification") logrus.Debug("Extracting certificates from provided SVID") @@ -82,6 +83,8 @@ func (verifier *SvidVerifier) verifyAndExtractSpiffeIdFromX509(svid string) (str svidPrincipalCert := svidCertChain[0] logrus.Debug("Building map of domains -> trusted certificate pools") + // reads these in reverse order of priority, so in a list of [file, spire], if there are domain conflicts, spire domains will dominate + // TODO: pre-build and store this (regenerating when Spire truststore updates) so it doesn't have to be regenerated for each request trustedCertificatePools := make(map[string]*x509.CertPool, 0) for _, source := range verifier.trustSources { for domain, certificates := range source.TrustedCertificates() { diff --git a/internal/common/svidverifier_test.go b/internal/common/svidverifier_test.go new file mode 100644 index 0000000..8b43c09 --- /dev/null +++ b/internal/common/svidverifier_test.go @@ -0,0 +1,93 @@ +package common + +import ( + "crypto/x509" + "encoding/pem" + "testing" + + "github.com/spf13/afero" + "github.com/spiffe/go-spiffe/spiffetest" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func certToFile(cert *x509.Certificate, fileName string) { + block := &pem.Block{ + Type: "CERTIFICATE", + Bytes: cert.Raw, + } + afero.WriteFile(appFS, fileName, pem.EncodeToMemory(block), 600) +} + +func TestValid(t *testing.T) { + appFS = afero.NewMemMapFs() + + ca := spiffetest.NewCA(t) + certToFile(ca.Roots()[0], "ca.pem") + svidFoo, _ := ca.CreateX509SVID("spiffe://example.org/foo") + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"ca.pem"}, + }) + require.NoError(t, err) + + verif := NewSvidVerifier() + verif.AddTrustSource(source) + + svidBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: svidFoo[0].Raw, + } + + id, err := verif.VerifyAndExtractSpiffeID(string(pem.EncodeToMemory(svidBlock))) + assert.Equal(t, "spiffe://example.org/foo", id) +} + +func TestDifferentDomain(t *testing.T) { + appFS = afero.NewMemMapFs() + + ca := spiffetest.NewCA(t) + certToFile(ca.Roots()[0], "ca.pem") + svidFoo, _ := ca.CreateX509SVID("spiffe://wrong.org/foo") + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"ca.pem"}, + }) + require.NoError(t, err) + + verif := NewSvidVerifier() + verif.AddTrustSource(source) + + svidBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: svidFoo[0].Raw, + } + + _, err = verif.VerifyAndExtractSpiffeID(string(pem.EncodeToMemory(svidBlock))) + assert.Error(t, err) +} + +func TestBadCA(t *testing.T) { + appFS = afero.NewMemMapFs() + + ca := spiffetest.NewCA(t) + certToFile(ca.Roots()[0], "ca.pem") + ca2 := spiffetest.NewCA(t) + svidFoo, _ := ca2.CreateX509SVID("spiffe://example.org/foo") + + source, err := NewFileTrustSource(map[string][]string{ + "spiffe://example.org": []string{"ca.pem"}, + }) + require.NoError(t, err) + + verif := NewSvidVerifier() + verif.AddTrustSource(source) + + svidBlock := &pem.Block{ + Type: "CERTIFICATE", + Bytes: svidFoo[0].Raw, + } + + _, err = verif.VerifyAndExtractSpiffeID(string(pem.EncodeToMemory(svidBlock))) + assert.Error(t, err) +} diff --git a/internal/common/trustsource.go b/internal/common/trustsource.go index 00cfbb5..98614fd 100644 --- a/internal/common/trustsource.go +++ b/internal/common/trustsource.go @@ -20,6 +20,8 @@ import ( "crypto/x509" ) +// TrustSource is an interface that lets sources of trust return a map of SPIFFE domain +// names to x509 certificates type TrustSource interface { TrustedCertificates() map[string][]*x509.Certificate } diff --git a/vault-auth-spire-filesource.json b/vault-auth-spire-filesource.json new file mode 100644 index 0000000..d755d45 --- /dev/null +++ b/vault-auth-spire-filesource.json @@ -0,0 +1,20 @@ +{ + "trustsource": { + "spire": { + "certLocation": "/tmp/vault-spire-certs.json", + "storeEnabled": true, + "domains": { + "spiffe://dev.foo.com": "unix:///tmp/agent.sock" + } + } + }, + + "log": { + "filename": "/tmp/vault-auth-spire.log", + "level": "DEBUG", + "maxSize": 10, + "maxBackups": 4, + "maxAge": 14, + "compress": true + } +} \ No newline at end of file