summaryrefslogtreecommitdiffstats
path: root/vendor/golang.org/x/oauth2
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2021-02-17 04:47:24 +0100
committerGitHub <noreply@github.com>2021-02-16 22:47:24 -0500
commitfe628d8406632e6f5b3969ac86d817a035d4bae9 (patch)
treecf29502ba516dcceb6d36c818d6596bfc6715ffd /vendor/golang.org/x/oauth2
parentdc707aea090741acb48d370152e65aa37d89800b (diff)
downloadgitea-fe628d8406632e6f5b3969ac86d817a035d4bae9.tar.gz
gitea-fe628d8406632e6f5b3969ac86d817a035d4bae9.zip
Vendor Update (#14696)
* github.com/yuin/goldmark v1.3.1 -> v1.3.2 * github.com/xanzy/go-gitlab v0.42.0 -> v0.44.0 * github.com/prometheus/client_golang v1.8.0 -> v1.9.0 * github.com/minio/minio-go v7.0.7 -> v7.0.9 * github.com/lafriks/xormstore v1.3.2 -> v1.4.0 Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'vendor/golang.org/x/oauth2')
-rw-r--r--vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go283
-rw-r--r--vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go32
-rw-r--r--vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go10
3 files changed, 289 insertions, 36 deletions
diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go
index 906d1fe9d3..2f078f73a5 100644
--- a/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go
+++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go
@@ -5,41 +5,55 @@
package externalaccount
import (
+ "context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
+ "encoding/json"
"errors"
"fmt"
+ "golang.org/x/oauth2"
"io"
"io/ioutil"
"net/http"
+ "net/url"
+ "os"
"path"
"sort"
"strings"
"time"
)
-// RequestSigner is a utility class to sign http requests using a AWS V4 signature.
+type awsSecurityCredentials struct {
+ AccessKeyID string `json:"AccessKeyID"`
+ SecretAccessKey string `json:"SecretAccessKey"`
+ SecurityToken string `json:"Token"`
+}
+
+// awsRequestSigner is a utility class to sign http requests using a AWS V4 signature.
type awsRequestSigner struct {
RegionName string
- AwsSecurityCredentials map[string]string
+ AwsSecurityCredentials awsSecurityCredentials
}
+// getenv aliases os.Getenv for testing
+var getenv = os.Getenv
+
const (
-// AWS Signature Version 4 signing algorithm identifier.
+ // AWS Signature Version 4 signing algorithm identifier.
awsAlgorithm = "AWS4-HMAC-SHA256"
-// The termination string for the AWS credential scope value as defined in
-// https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
+ // The termination string for the AWS credential scope value as defined in
+ // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
awsRequestType = "aws4_request"
-// The AWS authorization header name for the security session token if available.
+ // The AWS authorization header name for the security session token if available.
awsSecurityTokenHeader = "x-amz-security-token"
-// The AWS authorization header name for the auto-generated date.
+ // The AWS authorization header name for the auto-generated date.
awsDateHeader = "x-amz-date"
- awsTimeFormatLong = "20060102T150405Z"
+ awsTimeFormatLong = "20060102T150405Z"
awsTimeFormatShort = "20060102"
)
@@ -167,8 +181,8 @@ func (rs *awsRequestSigner) SignRequest(req *http.Request) error {
signedRequest.Header.Add("host", requestHost(req))
- if securityToken, ok := rs.AwsSecurityCredentials["security_token"]; ok {
- signedRequest.Header.Add(awsSecurityTokenHeader, securityToken)
+ if rs.AwsSecurityCredentials.SecurityToken != "" {
+ signedRequest.Header.Add(awsSecurityTokenHeader, rs.AwsSecurityCredentials.SecurityToken)
}
if signedRequest.Header.Get("date") == "" {
@@ -186,15 +200,6 @@ func (rs *awsRequestSigner) SignRequest(req *http.Request) error {
}
func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp time.Time) (string, error) {
- secretAccessKey, ok := rs.AwsSecurityCredentials["secret_access_key"]
- if !ok {
- return "", errors.New("oauth2/google: missing secret_access_key header")
- }
- accessKeyId, ok := rs.AwsSecurityCredentials["access_key_id"]
- if !ok {
- return "", errors.New("oauth2/google: missing access_key_id header")
- }
-
canonicalHeaderColumns, canonicalHeaderData := canonicalHeaders(req)
dateStamp := timestamp.Format(awsTimeFormatShort)
@@ -203,28 +208,258 @@ func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp
serviceName = splitHost[0]
}
- credentialScope := fmt.Sprintf("%s/%s/%s/%s",dateStamp, rs.RegionName, serviceName, awsRequestType)
+ credentialScope := fmt.Sprintf("%s/%s/%s/%s", dateStamp, rs.RegionName, serviceName, awsRequestType)
requestString, err := canonicalRequest(req, canonicalHeaderColumns, canonicalHeaderData)
if err != nil {
return "", err
}
requestHash, err := getSha256([]byte(requestString))
- if err != nil{
+ if err != nil {
return "", err
}
stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", awsAlgorithm, timestamp.Format(awsTimeFormatLong), credentialScope, requestHash)
- signingKey := []byte("AWS4" + secretAccessKey)
+ signingKey := []byte("AWS4" + rs.AwsSecurityCredentials.SecretAccessKey)
for _, signingInput := range []string{
dateStamp, rs.RegionName, serviceName, awsRequestType, stringToSign,
} {
signingKey, err = getHmacSha256(signingKey, []byte(signingInput))
- if err != nil{
+ if err != nil {
+ return "", err
+ }
+ }
+
+ return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, rs.AwsSecurityCredentials.AccessKeyID, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil
+}
+
+type awsCredentialSource struct {
+ EnvironmentID string
+ RegionURL string
+ RegionalCredVerificationURL string
+ CredVerificationURL string
+ TargetResource string
+ requestSigner *awsRequestSigner
+ region string
+ ctx context.Context
+ client *http.Client
+}
+
+type awsRequestHeader struct {
+ Key string `json:"key"`
+ Value string `json:"value"`
+}
+
+type awsRequest struct {
+ URL string `json:"url"`
+ Method string `json:"method"`
+ Headers []awsRequestHeader `json:"headers"`
+}
+
+func (cs awsCredentialSource) doRequest(req *http.Request) (*http.Response, error) {
+ if cs.client == nil {
+ cs.client = oauth2.NewClient(cs.ctx, nil)
+ }
+ return cs.client.Do(req.WithContext(cs.ctx))
+}
+
+func (cs awsCredentialSource) subjectToken() (string, error) {
+ if cs.requestSigner == nil {
+ awsSecurityCredentials, err := cs.getSecurityCredentials()
+ if err != nil {
return "", err
}
+
+ if cs.region, err = cs.getRegion(); err != nil {
+ return "", err
+ }
+
+ cs.requestSigner = &awsRequestSigner{
+ RegionName: cs.region,
+ AwsSecurityCredentials: awsSecurityCredentials,
+ }
+ }
+
+ // Generate the signed request to AWS STS GetCallerIdentity API.
+ // Use the required regional endpoint. Otherwise, the request will fail.
+ req, err := http.NewRequest("POST", strings.Replace(cs.RegionalCredVerificationURL, "{region}", cs.region, 1), nil)
+ if err != nil {
+ return "", err
+ }
+ // The full, canonical resource name of the workload identity pool
+ // provider, with or without the HTTPS prefix.
+ // Including this header as part of the signature is recommended to
+ // ensure data integrity.
+ if cs.TargetResource != "" {
+ req.Header.Add("x-goog-cloud-target-resource", cs.TargetResource)
+ }
+ cs.requestSigner.SignRequest(req)
+
+ /*
+ The GCP STS endpoint expects the headers to be formatted as:
+ # [
+ # {key: 'x-amz-date', value: '...'},
+ # {key: 'Authorization', value: '...'},
+ # ...
+ # ]
+ # And then serialized as:
+ # quote(json.dumps({
+ # url: '...',
+ # method: 'POST',
+ # headers: [{key: 'x-amz-date', value: '...'}, ...]
+ # }))
+ */
+
+ awsSignedReq := awsRequest{
+ URL: req.URL.String(),
+ Method: "POST",
+ }
+ for headerKey, headerList := range req.Header {
+ for _, headerValue := range headerList {
+ awsSignedReq.Headers = append(awsSignedReq.Headers, awsRequestHeader{
+ Key: headerKey,
+ Value: headerValue,
+ })
+ }
+ }
+ sort.Slice(awsSignedReq.Headers, func(i, j int) bool {
+ headerCompare := strings.Compare(awsSignedReq.Headers[i].Key, awsSignedReq.Headers[j].Key)
+ if headerCompare == 0 {
+ return strings.Compare(awsSignedReq.Headers[i].Value, awsSignedReq.Headers[j].Value) < 0
+ }
+ return headerCompare < 0
+ })
+
+ result, err := json.Marshal(awsSignedReq)
+ if err != nil {
+ return "", err
+ }
+ return url.QueryEscape(string(result)), nil
+}
+
+func (cs *awsCredentialSource) getRegion() (string, error) {
+ if envAwsRegion := getenv("AWS_REGION"); envAwsRegion != "" {
+ return envAwsRegion, nil
+ }
+
+ if cs.RegionURL == "" {
+ return "", errors.New("oauth2/google: unable to determine AWS region")
+ }
+
+ req, err := http.NewRequest("GET", cs.RegionURL, nil)
+ if err != nil {
+ return "", err
+ }
+
+ resp, err := cs.doRequest(req)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
+ if err != nil {
+ return "", err
+ }
+
+ if resp.StatusCode != 200 {
+ return "", fmt.Errorf("oauth2/google: unable to retrieve AWS region - %s", string(respBody))
+ }
+
+ // This endpoint will return the region in format: us-east-2b.
+ // Only the us-east-2 part should be used.
+ respBodyEnd := 0
+ if len(respBody) > 1 {
+ respBodyEnd = len(respBody) - 1
+ }
+ return string(respBody[:respBodyEnd]), nil
+}
+
+func (cs *awsCredentialSource) getSecurityCredentials() (result awsSecurityCredentials, err error) {
+ if accessKeyID := getenv("AWS_ACCESS_KEY_ID"); accessKeyID != "" {
+ if secretAccessKey := getenv("AWS_SECRET_ACCESS_KEY"); secretAccessKey != "" {
+ return awsSecurityCredentials{
+ AccessKeyID: accessKeyID,
+ SecretAccessKey: secretAccessKey,
+ SecurityToken: getenv("AWS_SESSION_TOKEN"),
+ }, nil
+ }
+ }
+
+ roleName, err := cs.getMetadataRoleName()
+ if err != nil {
+ return
+ }
+
+ credentials, err := cs.getMetadataSecurityCredentials(roleName)
+ if err != nil {
+ return
+ }
+
+ if credentials.AccessKeyID == "" {
+ return result, errors.New("oauth2/google: missing AccessKeyId credential")
+ }
+
+ if credentials.SecretAccessKey == "" {
+ return result, errors.New("oauth2/google: missing SecretAccessKey credential")
+ }
+
+ return credentials, nil
+}
+
+func (cs *awsCredentialSource) getMetadataSecurityCredentials(roleName string) (awsSecurityCredentials, error) {
+ var result awsSecurityCredentials
+
+ req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", cs.CredVerificationURL, roleName), nil)
+ if err != nil {
+ return result, err
+ }
+ req.Header.Add("Content-Type", "application/json")
+
+ resp, err := cs.doRequest(req)
+ if err != nil {
+ return result, err
+ }
+ defer resp.Body.Close()
+
+ respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
+ if err != nil {
+ return result, err
+ }
+
+ if resp.StatusCode != 200 {
+ return result, fmt.Errorf("oauth2/google: unable to retrieve AWS security credentials - %s", string(respBody))
+ }
+
+ err = json.Unmarshal(respBody, &result)
+ return result, err
+}
+
+func (cs *awsCredentialSource) getMetadataRoleName() (string, error) {
+ if cs.CredVerificationURL == "" {
+ return "", errors.New("oauth2/google: unable to determine the AWS metadata server security credentials endpoint")
+ }
+
+ req, err := http.NewRequest("GET", cs.CredVerificationURL, nil)
+ if err != nil {
+ return "", err
+ }
+
+ resp, err := cs.doRequest(req)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
+ if err != nil {
+ return "", err
+ }
+
+ if resp.StatusCode != 200 {
+ return "", fmt.Errorf("oauth2/google: unable to retrieve AWS role name - %s", string(respBody))
}
- return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, accessKeyId, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil
+ return string(respBody), nil
}
diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
index deb9deb730..57a5870973 100644
--- a/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
+++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
@@ -9,6 +9,7 @@ import (
"fmt"
"golang.org/x/oauth2"
"net/http"
+ "strconv"
"time"
)
@@ -77,13 +78,27 @@ type CredentialSource struct {
}
// parse determines the type of CredentialSource needed
-func (c *Config) parse(ctx context.Context) baseCredentialSource {
- if c.CredentialSource.File != "" {
- return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format}
+func (c *Config) parse(ctx context.Context) (baseCredentialSource, error) {
+ if len(c.CredentialSource.EnvironmentID) > 3 && c.CredentialSource.EnvironmentID[:3] == "aws" {
+ if awsVersion, err := strconv.Atoi(c.CredentialSource.EnvironmentID[3:]); err == nil {
+ if awsVersion != 1 {
+ return nil, fmt.Errorf("oauth2/google: aws version '%d' is not supported in the current build", awsVersion)
+ }
+ return awsCredentialSource{
+ EnvironmentID: c.CredentialSource.EnvironmentID,
+ RegionURL: c.CredentialSource.RegionURL,
+ RegionalCredVerificationURL: c.CredentialSource.RegionalCredVerificationURL,
+ CredVerificationURL: c.CredentialSource.URL,
+ TargetResource: c.Audience,
+ ctx: ctx,
+ }, nil
+ }
+ } else if c.CredentialSource.File != "" {
+ return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format}, nil
} else if c.CredentialSource.URL != "" {
- return urlCredentialSource{URL: c.CredentialSource.URL, Format: c.CredentialSource.Format, ctx: ctx}
+ return urlCredentialSource{URL: c.CredentialSource.URL, Format: c.CredentialSource.Format, ctx: ctx}, nil
}
- return nil
+ return nil, fmt.Errorf("oauth2/google: unable to parse credential source")
}
type baseCredentialSource interface {
@@ -100,11 +115,12 @@ type tokenSource struct {
func (ts tokenSource) Token() (*oauth2.Token, error) {
conf := ts.conf
- credSource := conf.parse(ts.ctx)
- if credSource == nil {
- return nil, fmt.Errorf("oauth2/google: unable to parse credential source")
+ credSource, err := conf.parse(ts.ctx)
+ if err != nil {
+ return nil, err
}
subjectToken, err := credSource.subjectToken()
+
if err != nil {
return nil, err
}
diff --git a/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go b/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go
index c7d85a3c20..1a1c9b411a 100644
--- a/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go
+++ b/vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go
@@ -32,11 +32,13 @@ func ExchangeToken(ctx context.Context, endpoint string, request *STSTokenExchan
data.Set("subject_token_type", request.SubjectTokenType)
data.Set("subject_token", request.SubjectToken)
data.Set("scope", strings.Join(request.Scope, " "))
- opts, err := json.Marshal(options)
- if err != nil {
- return nil, fmt.Errorf("oauth2/google: failed to marshal additional options: %v", err)
+ if options != nil {
+ opts, err := json.Marshal(options)
+ if err != nil {
+ return nil, fmt.Errorf("oauth2/google: failed to marshal additional options: %v", err)
+ }
+ data.Set("options", string(opts))
}
- data.Set("options", string(opts))
authentication.InjectAuthentication(data, headers)
encodedData := data.Encode()