diff --git a/go.mod b/go.mod index 050c5290cb3..e8847313025 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.4 github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 - github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 + github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 go.opentelemetry.io/otel v1.27.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.27.0 go.opentelemetry.io/otel/sdk v1.27.0 @@ -113,13 +113,13 @@ require ( github.com/googleapis/gax-go/v2 v2.12.4 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.6 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hashicorp/vault/api v1.12.2 // indirect + github.com/hashicorp/vault/api v1.14.0 // indirect github.com/jellydator/ttlcache/v3 v3.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/letsencrypt/boulder v0.0.0-20230907030200-6d76a0f91e1e // indirect diff --git a/go.sum b/go.sum index 32253a1d6d3..e1bf3f7c76f 100644 --- a/go.sum +++ b/go.sum @@ -1315,17 +1315,16 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 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 v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0= -github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.6 h1:TwRYfx2z2C4cLbXmT8I5PgP/xmuqASDyiVuGYfs9GZM= +github.com/hashicorp/go-retryablehttp v0.7.6/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -1353,8 +1352,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/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE= -github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE= +github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= +github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -1712,8 +1711,8 @@ github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 h1:xgbPRCr2npmmsuVVt github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3/go.mod h1:G4+I83FILPX6MtnoaUdmv/bRGEVtR3JdLeJa/kXdk/0= github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 h1:fjnDR5Lw9ElfOSRUGKkgwjaynqj93nLu0twAw+QxhHE= github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4/go.mod h1:9KFn5MwelyNoFXu3gNyVzvN/yAhcL6FE053oxih9+vM= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 h1:h9G8j+Ds21zqqulDbA/R/ft64oQQIyp8S7wJYABYSlg= -github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3/go.mod h1:zgCeHOuqF6k7A7TTEvftcA9V3FRzB7mrPtHOhXAQBnc= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 h1:QEXOb+feQmNOyLVT+FrghBqKKK4QDMP5dyic8RZHXdE= +github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4/go.mod h1:ohOhV9zclcIpNAWS0kq2ASB3EPPuRce2HjgXXaU3pKQ= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/vendor/github.com/hashicorp/go-retryablehttp/.go-version b/vendor/github.com/hashicorp/go-retryablehttp/.go-version new file mode 100644 index 00000000000..6fee2fedb0a --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/.go-version @@ -0,0 +1 @@ +1.22.2 diff --git a/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md b/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md new file mode 100644 index 00000000000..0c4c7a2bbcf --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/CHANGELOG.md @@ -0,0 +1,27 @@ +## 0.7.6 (May 9, 2024) + +ENHANCEMENTS: + +- client: support a `RetryPrepare` function for modifying the request before retrying (#216) +- client: support HTTP-date values for `Retry-After` header value (#138) +- client: avoid reading entire body when the body is a `*bytes.Reader` (#197) + +BUG FIXES: + +- client: fix a broken check for invalid server certificate in go 1.20+ (#210) + +## 0.7.5 (Nov 8, 2023) + +BUG FIXES: + +- client: fixes an issue where the request body is not preserved on temporary redirects or re-established HTTP/2 connections (#207) + +## 0.7.4 (Jun 6, 2023) + +BUG FIXES: + +- client: fixing an issue where the Content-Type header wouldn't be sent with an empty payload when using HTTP/2 (#194) + +## 0.7.3 (May 15, 2023) + +Initial release diff --git a/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS b/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS new file mode 100644 index 00000000000..d6dd78a2dd9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/CODEOWNERS @@ -0,0 +1 @@ +* @hashicorp/go-retryablehttp-maintainers diff --git a/vendor/github.com/hashicorp/go-retryablehttp/LICENSE b/vendor/github.com/hashicorp/go-retryablehttp/LICENSE index e87a115e462..f4f97ee5853 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/LICENSE +++ b/vendor/github.com/hashicorp/go-retryablehttp/LICENSE @@ -1,3 +1,5 @@ +Copyright (c) 2015 HashiCorp, Inc. + Mozilla Public License, version 2.0 1. Definitions diff --git a/vendor/github.com/hashicorp/go-retryablehttp/Makefile b/vendor/github.com/hashicorp/go-retryablehttp/Makefile index da17640e644..5255241961e 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/Makefile +++ b/vendor/github.com/hashicorp/go-retryablehttp/Makefile @@ -2,7 +2,7 @@ default: test test: go vet ./... - go test -race ./... + go test -v -race ./... updatedeps: go get -f -t -u ./... diff --git a/vendor/github.com/hashicorp/go-retryablehttp/README.md b/vendor/github.com/hashicorp/go-retryablehttp/README.md index 8943becf19b..145a62f218c 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/README.md +++ b/vendor/github.com/hashicorp/go-retryablehttp/README.md @@ -59,4 +59,4 @@ standardClient := retryClient.StandardClient() // *http.Client ``` For more usage and examples see the -[godoc](http://godoc.org/github.com/hashicorp/go-retryablehttp). +[pkg.go.dev](https://pkg.go.dev/github.com/hashicorp/go-retryablehttp). diff --git a/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go new file mode 100644 index 00000000000..b2b27e87225 --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go119.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build !go1.20 +// +build !go1.20 + +package retryablehttp + +import "crypto/x509" + +func isCertError(err error) bool { + _, ok := err.(x509.UnknownAuthorityError) + return ok +} diff --git a/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go new file mode 100644 index 00000000000..a3cd315a28b --- /dev/null +++ b/vendor/github.com/hashicorp/go-retryablehttp/cert_error_go120.go @@ -0,0 +1,14 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +//go:build go1.20 +// +build go1.20 + +package retryablehttp + +import "crypto/tls" + +func isCertError(err error) bool { + _, ok := err.(*tls.CertificateVerificationError) + return ok +} diff --git a/vendor/github.com/hashicorp/go-retryablehttp/client.go b/vendor/github.com/hashicorp/go-retryablehttp/client.go index f40d2411cf1..12ac50bcc45 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/client.go +++ b/vendor/github.com/hashicorp/go-retryablehttp/client.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + // Package retryablehttp provides a familiar HTTP client interface with // automatic retries and exponential backoff. It is a thin wrapper over the // standard net/http client library and exposes nearly the same public API. @@ -24,10 +27,8 @@ package retryablehttp import ( "bytes" "context" - "crypto/x509" "fmt" "io" - "io/ioutil" "log" "math" "math/rand" @@ -60,6 +61,10 @@ var ( // limit the size we consume to respReadLimit. respReadLimit = int64(4096) + // timeNow sets the function that returns the current time. + // This defaults to time.Now. Changes to this should only be done in tests. + timeNow = time.Now + // A regular expression to match the error returned by net/http when the // configured number of redirects is exhausted. This error isn't typed // specifically so we resort to matching on the error string. @@ -70,6 +75,11 @@ var ( // specifically so we resort to matching on the error string. schemeErrorRe = regexp.MustCompile(`unsupported protocol scheme`) + // A regular expression to match the error returned by net/http when a + // request header or value is invalid. This error isn't typed + // specifically so we resort to matching on the error string. + invalidHeaderErrorRe = regexp.MustCompile(`invalid header`) + // A regular expression to match the error returned by net/http when the // TLS certificate is not trusted. This error isn't typed // specifically so we resort to matching on the error string. @@ -157,6 +167,20 @@ func (r *Request) SetBody(rawBody interface{}) error { } r.body = bodyReader r.ContentLength = contentLength + if bodyReader != nil { + r.GetBody = func() (io.ReadCloser, error) { + body, err := bodyReader() + if err != nil { + return nil, err + } + if rc, ok := body.(io.ReadCloser); ok { + return rc, nil + } + return io.NopCloser(body), nil + } + } else { + r.GetBody = func() (io.ReadCloser, error) { return http.NoBody, nil } + } return nil } @@ -231,21 +255,19 @@ func getBodyReaderAndContentLength(rawBody interface{}) (ReaderFunc, int64, erro // deal with it seeking so want it to match here instead of the // io.ReadSeeker case. case *bytes.Reader: - buf, err := ioutil.ReadAll(body) - if err != nil { - return nil, 0, err - } + snapshot := *body bodyReader = func() (io.Reader, error) { - return bytes.NewReader(buf), nil + r := snapshot + return &r, nil } - contentLength = int64(len(buf)) + contentLength = int64(body.Len()) // Compat case case io.ReadSeeker: raw := body bodyReader = func() (io.Reader, error) { _, err := raw.Seek(0, 0) - return ioutil.NopCloser(raw), err + return io.NopCloser(raw), err } if lr, ok := raw.(LenReader); ok { contentLength = int64(lr.Len()) @@ -253,14 +275,21 @@ func getBodyReaderAndContentLength(rawBody interface{}) (ReaderFunc, int64, erro // Read all in so we can reset case io.Reader: - buf, err := ioutil.ReadAll(body) + buf, err := io.ReadAll(body) if err != nil { return nil, 0, err } - bodyReader = func() (io.Reader, error) { - return bytes.NewReader(buf), nil + if len(buf) == 0 { + bodyReader = func() (io.Reader, error) { + return http.NoBody, nil + } + contentLength = 0 + } else { + bodyReader = func() (io.Reader, error) { + return bytes.NewReader(buf), nil + } + contentLength = int64(len(buf)) } - contentLength = int64(len(buf)) // No body provided, nothing to do case nil: @@ -292,18 +321,19 @@ func NewRequest(method, url string, rawBody interface{}) (*Request, error) { // The context controls the entire lifetime of a request and its response: // obtaining a connection, sending the request, and reading the response headers and body. func NewRequestWithContext(ctx context.Context, method, url string, rawBody interface{}) (*Request, error) { - bodyReader, contentLength, err := getBodyReaderAndContentLength(rawBody) + httpReq, err := http.NewRequestWithContext(ctx, method, url, nil) if err != nil { return nil, err } - httpReq, err := http.NewRequestWithContext(ctx, method, url, nil) - if err != nil { + req := &Request{ + Request: httpReq, + } + if err := req.SetBody(rawBody); err != nil { return nil, err } - httpReq.ContentLength = contentLength - return &Request{body: bodyReader, Request: httpReq}, nil + return req, nil } // Logger interface allows to use other loggers than @@ -368,6 +398,9 @@ type Backoff func(min, max time.Duration, attemptNum int, resp *http.Response) t // attempted. If overriding this, be sure to close the body if needed. type ErrorHandler func(resp *http.Response, err error, numTries int) (*http.Response, error) +// PrepareRetry is called before retry operation. It can be used for example to re-sign the request +type PrepareRetry func(req *http.Request) error + // Client is used to make HTTP requests. It adds additional functionality // like automatic retries to tolerate minor outages. type Client struct { @@ -396,6 +429,9 @@ type Client struct { // ErrorHandler specifies the custom error handler to use, if any ErrorHandler ErrorHandler + // PrepareRetry can prepare the request for retry operation, for example re-sign it + PrepareRetry PrepareRetry + loggerInit sync.Once clientInit sync.Once } @@ -469,11 +505,16 @@ func baseRetryPolicy(resp *http.Response, err error) (bool, error) { return false, v } + // Don't retry if the error was due to an invalid header. + if invalidHeaderErrorRe.MatchString(v.Error()) { + return false, v + } + // Don't retry if the error was due to TLS cert verification failure. if notTrustedErrorRe.MatchString(v.Error()) { return false, v } - if _, ok := v.Err.(x509.UnknownAuthorityError); ok { + if isCertError(v.Err) { return false, v } } @@ -510,10 +551,8 @@ func baseRetryPolicy(resp *http.Response, err error) (bool, error) { func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration { if resp != nil { if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode == http.StatusServiceUnavailable { - if s, ok := resp.Header["Retry-After"]; ok { - if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil { - return time.Second * time.Duration(sleep) - } + if sleep, ok := parseRetryAfterHeader(resp.Header["Retry-After"]); ok { + return sleep } } } @@ -526,6 +565,41 @@ func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) return sleep } +// parseRetryAfterHeader parses the Retry-After header and returns the +// delay duration according to the spec: https://httpwg.org/specs/rfc7231.html#header.retry-after +// The bool returned will be true if the header was successfully parsed. +// Otherwise, the header was either not present, or was not parseable according to the spec. +// +// Retry-After headers come in two flavors: Seconds or HTTP-Date +// +// Examples: +// * Retry-After: Fri, 31 Dec 1999 23:59:59 GMT +// * Retry-After: 120 +func parseRetryAfterHeader(headers []string) (time.Duration, bool) { + if len(headers) == 0 || headers[0] == "" { + return 0, false + } + header := headers[0] + // Retry-After: 120 + if sleep, err := strconv.ParseInt(header, 10, 64); err == nil { + if sleep < 0 { // a negative sleep doesn't make sense + return 0, false + } + return time.Second * time.Duration(sleep), true + } + + // Retry-After: Fri, 31 Dec 1999 23:59:59 GMT + retryTime, err := time.Parse(time.RFC1123, header) + if err != nil { + return 0, false + } + if until := retryTime.Sub(timeNow()); until > 0 { + return until, true + } + // date is in the past + return 0, true +} + // LinearJitterBackoff provides a callback for Client.Backoff which will // perform linear backoff based on the attempt number and with jitter to // prevent a thundering herd. @@ -553,13 +627,13 @@ func LinearJitterBackoff(min, max time.Duration, attemptNum int, resp *http.Resp } // Seed rand; doing this every time is fine - rand := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) + source := rand.New(rand.NewSource(int64(time.Now().Nanosecond()))) // Pick a random number that lies somewhere between the min and max and // multiply by the attemptNum. attemptNum starts at zero so we always // increment here. We first get a random percentage, then apply that to the // difference between min and max, and add to min. - jitter := rand.Float64() * float64(max-min) + jitter := source.Float64() * float64(max-min) jitterMin := int64(jitter) + int64(min) return time.Duration(jitterMin * int64(attemptNum)) } @@ -593,10 +667,10 @@ func (c *Client) Do(req *Request) (*http.Response, error) { var resp *http.Response var attempt int var shouldRetry bool - var doErr, respErr, checkErr error + var doErr, respErr, checkErr, prepareErr error for i := 0; ; i++ { - doErr, respErr = nil, nil + doErr, respErr, prepareErr = nil, nil, nil attempt++ // Always rewind the request body when non-nil. @@ -609,7 +683,7 @@ func (c *Client) Do(req *Request) (*http.Response, error) { if c, ok := body.(io.ReadCloser); ok { req.Body = c } else { - req.Body = ioutil.NopCloser(body) + req.Body = io.NopCloser(body) } } @@ -703,17 +777,26 @@ func (c *Client) Do(req *Request) (*http.Response, error) { // without racing against the closeBody call in persistConn.writeLoop. httpreq := *req.Request req.Request = &httpreq + + if c.PrepareRetry != nil { + if err := c.PrepareRetry(req.Request); err != nil { + prepareErr = err + break + } + } } // this is the closest we have to success criteria - if doErr == nil && respErr == nil && checkErr == nil && !shouldRetry { + if doErr == nil && respErr == nil && checkErr == nil && prepareErr == nil && !shouldRetry { return resp, nil } defer c.HTTPClient.CloseIdleConnections() var err error - if checkErr != nil { + if prepareErr != nil { + err = prepareErr + } else if checkErr != nil { err = checkErr } else if respErr != nil { err = respErr @@ -745,7 +828,7 @@ func (c *Client) Do(req *Request) (*http.Response, error) { // Try to read the response body so we can reuse this connection. func (c *Client) drainBody(body io.ReadCloser) { defer body.Close() - _, err := io.Copy(ioutil.Discard, io.LimitReader(body, respReadLimit)) + _, err := io.Copy(io.Discard, io.LimitReader(body, respReadLimit)) if err != nil { if c.logger() != nil { switch v := c.logger().(type) { diff --git a/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go b/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go index 8f3ee358427..8c407adb3b4 100644 --- a/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go +++ b/vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package retryablehttp import ( diff --git a/vendor/github.com/hashicorp/vault/api/lifetime_watcher.go b/vendor/github.com/hashicorp/vault/api/lifetime_watcher.go index 5c060e5a150..4bc1390b93a 100644 --- a/vendor/github.com/hashicorp/vault/api/lifetime_watcher.go +++ b/vendor/github.com/hashicorp/vault/api/lifetime_watcher.go @@ -6,6 +6,7 @@ package api import ( "errors" "math/rand" + "strings" "sync" "time" @@ -31,6 +32,7 @@ var ( DefaultRenewerRenewBuffer = 5 ) +//go:generate enumer -type=RenewBehavior -trimprefix=RenewBehavior type RenewBehavior uint const ( @@ -288,12 +290,18 @@ func (r *LifetimeWatcher) doRenewWithOptions(tokenMode bool, nonRenewable bool, switch { case nonRenewable || r.renewBehavior == RenewBehaviorRenewDisabled: // Can't or won't renew, just keep the same expiration so we exit - // when it's reauthentication time + // when it's re-authentication time remainingLeaseDuration = fallbackLeaseDuration default: // Renew the token renewal, err = renew(credString, r.increment) + if err != nil && strings.Contains(err.Error(), "permission denied") { + // We can't renew since the token doesn't have permission to. Fall back + // to the code path for non-renewable tokens. + nonRenewable = true + continue + } if err != nil || renewal == nil || (tokenMode && renewal.Auth == nil) { if r.renewBehavior == RenewBehaviorErrorOnErrors { if err != nil { @@ -349,8 +357,11 @@ func (r *LifetimeWatcher) doRenewWithOptions(tokenMode bool, nonRenewable bool, if errorBackoff == nil { sleepDuration = r.calculateSleepDuration(remainingLeaseDuration, priorDuration) - } else if errorBackoff.NextBackOff() == backoff.Stop { - return err + } else { + sleepDuration = errorBackoff.NextBackOff() + if sleepDuration == backoff.Stop { + return err + } } // remainingLeaseDuration becomes the priorDuration for the next loop diff --git a/vendor/github.com/hashicorp/vault/api/plugin_helpers.go b/vendor/github.com/hashicorp/vault/api/plugin_helpers.go index 5d2593668b4..d330478f5bf 100644 --- a/vendor/github.com/hashicorp/vault/api/plugin_helpers.go +++ b/vendor/github.com/hashicorp/vault/api/plugin_helpers.go @@ -13,7 +13,8 @@ import ( "net/url" "os" - "github.com/go-jose/go-jose/v3/jwt" + jose "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" "github.com/hashicorp/errwrap" ) @@ -40,6 +41,11 @@ const ( // PluginUnwrapTokenEnv is the ENV name used to pass unwrap tokens to the // plugin. PluginUnwrapTokenEnv = "VAULT_UNWRAP_TOKEN" + + // CubbyHoleJWTSignatureAlgorithm is the signature algorithm used for + // the unwrap token that Vault passes to a plugin when auto-mTLS is + // not enabled. + CubbyHoleJWTSignatureAlgorithm = jose.ES512 ) // PluginAPIClientMeta is a helper that plugins can use to configure TLS connections @@ -102,7 +108,7 @@ func VaultPluginTLSProviderContext(ctx context.Context, apiTLSConfig *TLSConfig) return func() (*tls.Config, error) { unwrapToken := os.Getenv(PluginUnwrapTokenEnv) - parsedJWT, err := jwt.ParseSigned(unwrapToken) + parsedJWT, err := jwt.ParseSigned(unwrapToken, []jose.SignatureAlgorithm{CubbyHoleJWTSignatureAlgorithm}) if err != nil { return nil, errwrap.Wrapf("error parsing wrapping token: {{err}}", err) } diff --git a/vendor/github.com/hashicorp/vault/api/plugin_runtime_types.go b/vendor/github.com/hashicorp/vault/api/plugin_runtime_types.go index d3acd0d002c..2514f1279db 100644 --- a/vendor/github.com/hashicorp/vault/api/plugin_runtime_types.go +++ b/vendor/github.com/hashicorp/vault/api/plugin_runtime_types.go @@ -9,11 +9,9 @@ package api import "fmt" -var PluginRuntimeTypes = []PluginRuntimeType{ - PluginRuntimeTypeUnsupported, - PluginRuntimeTypeContainer, -} +var PluginRuntimeTypes = _PluginRuntimeTypeValues +//go:generate enumer -type=PluginRuntimeType -trimprefix=PluginRuntimeType -transform=snake type PluginRuntimeType uint32 // This is a list of PluginRuntimeTypes used by Vault. @@ -22,20 +20,11 @@ const ( PluginRuntimeTypeContainer ) -func (r PluginRuntimeType) String() string { - switch r { - case PluginRuntimeTypeContainer: - return "container" - default: - return "unsupported" - } -} - +// ParsePluginRuntimeType is a wrapper around PluginRuntimeTypeString kept for backwards compatibility. func ParsePluginRuntimeType(PluginRuntimeType string) (PluginRuntimeType, error) { - switch PluginRuntimeType { - case "container": - return PluginRuntimeTypeContainer, nil - default: + t, err := PluginRuntimeTypeString(PluginRuntimeType) + if err != nil { return PluginRuntimeTypeUnsupported, fmt.Errorf("%q is not a supported plugin runtime type", PluginRuntimeType) } + return t, nil } diff --git a/vendor/github.com/hashicorp/vault/api/pluginruntimetype_enumer.go b/vendor/github.com/hashicorp/vault/api/pluginruntimetype_enumer.go new file mode 100644 index 00000000000..663f440ff44 --- /dev/null +++ b/vendor/github.com/hashicorp/vault/api/pluginruntimetype_enumer.go @@ -0,0 +1,49 @@ +// Code generated by "enumer -type=PluginRuntimeType -trimprefix=PluginRuntimeType -transform=snake"; DO NOT EDIT. + +package api + +import ( + "fmt" +) + +const _PluginRuntimeTypeName = "unsupportedcontainer" + +var _PluginRuntimeTypeIndex = [...]uint8{0, 11, 20} + +func (i PluginRuntimeType) String() string { + if i >= PluginRuntimeType(len(_PluginRuntimeTypeIndex)-1) { + return fmt.Sprintf("PluginRuntimeType(%d)", i) + } + return _PluginRuntimeTypeName[_PluginRuntimeTypeIndex[i]:_PluginRuntimeTypeIndex[i+1]] +} + +var _PluginRuntimeTypeValues = []PluginRuntimeType{0, 1} + +var _PluginRuntimeTypeNameToValueMap = map[string]PluginRuntimeType{ + _PluginRuntimeTypeName[0:11]: 0, + _PluginRuntimeTypeName[11:20]: 1, +} + +// PluginRuntimeTypeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func PluginRuntimeTypeString(s string) (PluginRuntimeType, error) { + if val, ok := _PluginRuntimeTypeNameToValueMap[s]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to PluginRuntimeType values", s) +} + +// PluginRuntimeTypeValues returns all values of the enum +func PluginRuntimeTypeValues() []PluginRuntimeType { + return _PluginRuntimeTypeValues +} + +// IsAPluginRuntimeType returns "true" if the value is listed in the enum definition. "false" otherwise +func (i PluginRuntimeType) IsAPluginRuntimeType() bool { + for _, v := range _PluginRuntimeTypeValues { + if i == v { + return true + } + } + return false +} diff --git a/vendor/github.com/hashicorp/vault/api/renewbehavior_enumer.go b/vendor/github.com/hashicorp/vault/api/renewbehavior_enumer.go new file mode 100644 index 00000000000..9b272e3e0ce --- /dev/null +++ b/vendor/github.com/hashicorp/vault/api/renewbehavior_enumer.go @@ -0,0 +1,50 @@ +// Code generated by "enumer -type=RenewBehavior -trimprefix=RenewBehavior"; DO NOT EDIT. + +package api + +import ( + "fmt" +) + +const _RenewBehaviorName = "IgnoreErrorsRenewDisabledErrorOnErrors" + +var _RenewBehaviorIndex = [...]uint8{0, 12, 25, 38} + +func (i RenewBehavior) String() string { + if i >= RenewBehavior(len(_RenewBehaviorIndex)-1) { + return fmt.Sprintf("RenewBehavior(%d)", i) + } + return _RenewBehaviorName[_RenewBehaviorIndex[i]:_RenewBehaviorIndex[i+1]] +} + +var _RenewBehaviorValues = []RenewBehavior{0, 1, 2} + +var _RenewBehaviorNameToValueMap = map[string]RenewBehavior{ + _RenewBehaviorName[0:12]: 0, + _RenewBehaviorName[12:25]: 1, + _RenewBehaviorName[25:38]: 2, +} + +// RenewBehaviorString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func RenewBehaviorString(s string) (RenewBehavior, error) { + if val, ok := _RenewBehaviorNameToValueMap[s]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to RenewBehavior values", s) +} + +// RenewBehaviorValues returns all values of the enum +func RenewBehaviorValues() []RenewBehavior { + return _RenewBehaviorValues +} + +// IsARenewBehavior returns "true" if the value is listed in the enum definition. "false" otherwise +func (i RenewBehavior) IsARenewBehavior() bool { + for _, v := range _RenewBehaviorValues { + if i == v { + return true + } + } + return false +} diff --git a/vendor/github.com/hashicorp/vault/api/replication_status.go b/vendor/github.com/hashicorp/vault/api/replication_status.go index 9bc02d53935..d7224ff11d1 100644 --- a/vendor/github.com/hashicorp/vault/api/replication_status.go +++ b/vendor/github.com/hashicorp/vault/api/replication_status.go @@ -19,13 +19,14 @@ const ( ) type ClusterInfo struct { - APIAddr string `json:"api_address,omitempty" mapstructure:"api_address"` - ClusterAddress string `json:"cluster_address,omitempty" mapstructure:"cluster_address"` - ConnectionStatus string `json:"connection_status,omitempty" mapstructure:"connection_status"` - LastHeartBeat string `json:"last_heartbeat,omitempty" mapstructure:"last_heartbeat"` - LastHeartBeatDurationMillis string `json:"last_heartbeat_duration_ms,omitempty" mapstructure:"last_heartbeat_duration_ms"` - ClockSkewMillis string `json:"clock_skew_ms,omitempty" mapstructure:"clock_skew_ms"` - NodeID string `json:"node_id,omitempty" mapstructure:"node_id"` + APIAddr string `json:"api_address,omitempty" mapstructure:"api_address"` + ClusterAddress string `json:"cluster_address,omitempty" mapstructure:"cluster_address"` + ConnectionStatus string `json:"connection_status,omitempty" mapstructure:"connection_status"` + LastHeartBeat string `json:"last_heartbeat,omitempty" mapstructure:"last_heartbeat"` + LastHeartBeatDurationMillis string `json:"last_heartbeat_duration_ms,omitempty" mapstructure:"last_heartbeat_duration_ms"` + ClockSkewMillis string `json:"clock_skew_ms,omitempty" mapstructure:"clock_skew_ms"` + NodeID string `json:"node_id,omitempty" mapstructure:"node_id"` + ReplicationPrimaryCanaryAgeMillis string `json:"replication_primary_canary_age_ms,omitempty" mapstructure:"replication_primary_canary_age_ms"` } type ReplicationStatusGenericResponse struct { diff --git a/vendor/github.com/hashicorp/vault/api/sys_hastatus.go b/vendor/github.com/hashicorp/vault/api/sys_hastatus.go index 58a73b89cbb..2e54651e175 100644 --- a/vendor/github.com/hashicorp/vault/api/sys_hastatus.go +++ b/vendor/github.com/hashicorp/vault/api/sys_hastatus.go @@ -35,14 +35,15 @@ type HAStatusResponse struct { } type HANode struct { - Hostname string `json:"hostname"` - APIAddress string `json:"api_address"` - ClusterAddress string `json:"cluster_address"` - ActiveNode bool `json:"active_node"` - LastEcho *time.Time `json:"last_echo"` - EchoDurationMillis int64 `json:"echo_duration_ms"` - ClockSkewMillis int64 `json:"clock_skew_ms"` - Version string `json:"version"` - UpgradeVersion string `json:"upgrade_version,omitempty"` - RedundancyZone string `json:"redundancy_zone,omitempty"` + Hostname string `json:"hostname"` + APIAddress string `json:"api_address"` + ClusterAddress string `json:"cluster_address"` + ActiveNode bool `json:"active_node"` + LastEcho *time.Time `json:"last_echo"` + EchoDurationMillis int64 `json:"echo_duration_ms"` + ClockSkewMillis int64 `json:"clock_skew_ms"` + Version string `json:"version"` + UpgradeVersion string `json:"upgrade_version,omitempty"` + RedundancyZone string `json:"redundancy_zone,omitempty"` + ReplicationPrimaryCanaryAgeMillis int64 `json:"replication_primary_canary_age_ms"` } diff --git a/vendor/github.com/hashicorp/vault/api/sys_health.go b/vendor/github.com/hashicorp/vault/api/sys_health.go index 0dc849885ff..6868b96d77a 100644 --- a/vendor/github.com/hashicorp/vault/api/sys_health.go +++ b/vendor/github.com/hashicorp/vault/api/sys_health.go @@ -38,18 +38,19 @@ func (c *Sys) HealthWithContext(ctx context.Context) (*HealthResponse, error) { } type HealthResponse struct { - Initialized bool `json:"initialized"` - Sealed bool `json:"sealed"` - Standby bool `json:"standby"` - PerformanceStandby bool `json:"performance_standby"` - ReplicationPerformanceMode string `json:"replication_performance_mode"` - ReplicationDRMode string `json:"replication_dr_mode"` - ServerTimeUTC int64 `json:"server_time_utc"` - Version string `json:"version"` - ClusterName string `json:"cluster_name,omitempty"` - ClusterID string `json:"cluster_id,omitempty"` - LastWAL uint64 `json:"last_wal,omitempty"` - Enterprise bool `json:"enterprise"` - EchoDurationMillis int64 `json:"echo_duration_ms"` - ClockSkewMillis int64 `json:"clock_skew_ms"` + Initialized bool `json:"initialized"` + Sealed bool `json:"sealed"` + Standby bool `json:"standby"` + PerformanceStandby bool `json:"performance_standby"` + ReplicationPerformanceMode string `json:"replication_performance_mode"` + ReplicationDRMode string `json:"replication_dr_mode"` + ServerTimeUTC int64 `json:"server_time_utc"` + Version string `json:"version"` + ClusterName string `json:"cluster_name,omitempty"` + ClusterID string `json:"cluster_id,omitempty"` + LastWAL uint64 `json:"last_wal,omitempty"` + Enterprise bool `json:"enterprise"` + EchoDurationMillis int64 `json:"echo_duration_ms"` + ClockSkewMillis int64 `json:"clock_skew_ms"` + ReplicationPrimaryCanaryAgeMillis int64 `json:"replication_primary_canary_age_ms"` } diff --git a/vendor/github.com/hashicorp/vault/api/sys_raft.go b/vendor/github.com/hashicorp/vault/api/sys_raft.go index 4b9487c61d5..699f6e9fd09 100644 --- a/vendor/github.com/hashicorp/vault/api/sys_raft.go +++ b/vendor/github.com/hashicorp/vault/api/sys_raft.go @@ -9,6 +9,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "io/ioutil" "net/http" @@ -100,6 +101,23 @@ type AutopilotState struct { OptimisticFailureTolerance int `mapstructure:"optimistic_failure_tolerance,omitempty"` } +func (a *AutopilotState) String() string { + var result string + result += fmt.Sprintf("Healthy: %t. FailureTolerance: %d. Leader: %s. OptimisticFailureTolerance: %d\n", a.Healthy, a.FailureTolerance, a.Leader, a.OptimisticFailureTolerance) + for _, s := range a.Servers { + result += fmt.Sprintf("Server: %s\n", s) + } + result += fmt.Sprintf("Voters: %v\n", a.Voters) + result += fmt.Sprintf("NonVoters: %v\n", a.NonVoters) + + for name, zone := range a.RedundancyZones { + result += fmt.Sprintf("RedundancyZone %s: %s\n", name, &zone) + } + + result += fmt.Sprintf("Upgrade: %s", a.Upgrade) + return result +} + // AutopilotServer represents the server blocks in the response of the raft // autopilot state API. type AutopilotServer struct { @@ -119,12 +137,21 @@ type AutopilotServer struct { NodeType string `mapstructure:"node_type,omitempty"` } +func (a *AutopilotServer) String() string { + return fmt.Sprintf("ID: %s. Name: %s. Address: %s. NodeStatus: %s. LastContact: %s. LastTerm: %d. LastIndex: %d. Healthy: %t. StableSince: %s. Status: %s. Version: %s. UpgradeVersion: %s. RedundancyZone: %s. NodeType: %s", + a.ID, a.Name, a.Address, a.NodeStatus, a.LastContact, a.LastTerm, a.LastIndex, a.Healthy, a.StableSince, a.Status, a.Version, a.UpgradeVersion, a.RedundancyZone, a.NodeType) +} + type AutopilotZone struct { Servers []string `mapstructure:"servers,omitempty"` Voters []string `mapstructure:"voters,omitempty"` FailureTolerance int `mapstructure:"failure_tolerance,omitempty"` } +func (a *AutopilotZone) String() string { + return fmt.Sprintf("Servers: %v. Voters: %v. FailureTolerance: %d", a.Servers, a.Voters, a.FailureTolerance) +} + type AutopilotUpgrade struct { Status string `mapstructure:"status"` TargetVersion string `mapstructure:"target_version,omitempty"` @@ -137,6 +164,17 @@ type AutopilotUpgrade struct { RedundancyZones map[string]AutopilotZoneUpgradeVersions `mapstructure:"redundancy_zones,omitempty"` } +func (a *AutopilotUpgrade) String() string { + result := fmt.Sprintf("Status: %s. TargetVersion: %s. TargetVersionVoters: %v. TargetVersionNonVoters: %v. TargetVersionReadReplicas: %v. OtherVersionVoters: %v. OtherVersionNonVoters: %v. OtherVersionReadReplicas: %v", + a.Status, a.TargetVersion, a.TargetVersionVoters, a.TargetVersionNonVoters, a.TargetVersionReadReplicas, a.OtherVersionVoters, a.OtherVersionNonVoters, a.OtherVersionReadReplicas) + + for name, zone := range a.RedundancyZones { + result += fmt.Sprintf("Redundancy Zone %s: %s", name, zone) + } + + return result +} + type AutopilotZoneUpgradeVersions struct { TargetVersionVoters []string `mapstructure:"target_version_voters,omitempty"` TargetVersionNonVoters []string `mapstructure:"target_version_non_voters,omitempty"` @@ -144,6 +182,11 @@ type AutopilotZoneUpgradeVersions struct { OtherVersionNonVoters []string `mapstructure:"other_version_non_voters,omitempty"` } +func (a *AutopilotZoneUpgradeVersions) String() string { + return fmt.Sprintf("TargetVersionVoters: %v. TargetVersionNonVoters: %v. OtherVersionVoters: %v. OtherVersionNonVoters: %v", + a.TargetVersionVoters, a.TargetVersionNonVoters, a.OtherVersionVoters, a.OtherVersionNonVoters) +} + // RaftJoin wraps RaftJoinWithContext using context.Background. func (c *Sys) RaftJoin(opts *RaftJoinRequest) (*RaftJoinResponse, error) { return c.RaftJoinWithContext(context.Background(), opts) diff --git a/vendor/github.com/sigstore/sigstore/pkg/signature/kms/hashivault/client.go b/vendor/github.com/sigstore/sigstore/pkg/signature/kms/hashivault/client.go index 1f56f8051a6..20656bc8055 100644 --- a/vendor/github.com/sigstore/sigstore/pkg/signature/kms/hashivault/client.go +++ b/vendor/github.com/sigstore/sigstore/pkg/signature/kms/hashivault/client.go @@ -276,9 +276,10 @@ func (h hashivaultClient) sign(digest []byte, alg crypto.Hash, opts ...signature } signResult, err := client.Write(fmt.Sprintf("/%s/sign/%s%s", h.transitSecretEnginePath, h.keyPath, hashString(alg)), map[string]interface{}{ - "input": base64.StdEncoding.Strict().EncodeToString(digest), - "prehashed": alg != crypto.Hash(0), - "key_version": keyVersion, + "input": base64.StdEncoding.Strict().EncodeToString(digest), + "prehashed": alg != crypto.Hash(0), + "key_version": keyVersion, + "signature_algorithm": "pkcs1v15", }) if err != nil { return nil, fmt.Errorf("transit: failed to sign payload: %w", err) diff --git a/vendor/modules.txt b/vendor/modules.txt index 2d07bdf90c9..d1dbd07d8f3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -676,8 +676,8 @@ github.com/hashicorp/go-cleanhttp # github.com/hashicorp/go-multierror v1.1.1 ## explicit; go 1.13 github.com/hashicorp/go-multierror -# github.com/hashicorp/go-retryablehttp v0.7.2 -## explicit; go 1.13 +# github.com/hashicorp/go-retryablehttp v0.7.6 +## explicit; go 1.19 github.com/hashicorp/go-retryablehttp # github.com/hashicorp/go-rootcerts v1.0.2 ## explicit; go 1.12 @@ -709,8 +709,8 @@ github.com/hashicorp/hcl/hcl/token github.com/hashicorp/hcl/json/parser github.com/hashicorp/hcl/json/scanner github.com/hashicorp/hcl/json/token -# github.com/hashicorp/vault/api v1.12.2 -## explicit; go 1.19 +# github.com/hashicorp/vault/api v1.14.0 +## explicit; go 1.21 github.com/hashicorp/vault/api # github.com/imdario/mergo v0.3.13 ## explicit; go 1.13 @@ -890,8 +890,8 @@ github.com/sigstore/sigstore/pkg/signature/kms/azure # github.com/sigstore/sigstore/pkg/signature/kms/gcp v1.8.4 ## explicit; go 1.21 github.com/sigstore/sigstore/pkg/signature/kms/gcp -# github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.3 -## explicit; go 1.20 +# github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.8.4 +## explicit; go 1.21 github.com/sigstore/sigstore/pkg/signature/kms/hashivault # github.com/sirupsen/logrus v1.9.3 ## explicit; go 1.13