[#Issue] presign
Some checks failed
/ DCO (pull_request) Failing after 1m24s
/ Builds (1.20) (pull_request) Successful in 2m29s
/ Builds (1.21) (pull_request) Successful in 2m15s
/ Vulncheck (pull_request) Successful in 2m0s
/ Lint (pull_request) Failing after 2m31s
/ Tests (1.20) (pull_request) Successful in 2m18s
/ Tests (1.21) (pull_request) Failing after 11s
Some checks failed
/ DCO (pull_request) Failing after 1m24s
/ Builds (1.20) (pull_request) Successful in 2m29s
/ Builds (1.21) (pull_request) Successful in 2m15s
/ Vulncheck (pull_request) Successful in 2m0s
/ Lint (pull_request) Failing after 2m31s
/ Tests (1.20) (pull_request) Successful in 2m18s
/ Tests (1.21) (pull_request) Failing after 11s
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
4d8db3b38a
commit
978679f380
5 changed files with 40 additions and 20 deletions
|
@ -9,7 +9,6 @@ import (
|
|||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -23,7 +22,6 @@ import (
|
|||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
credentialsv2 "github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/smithy-go/logging"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -410,8 +408,6 @@ func (c *Center) checkSign(authHeader *AuthHeader, box *accessbox.Box, request *
|
|||
case signaturePreambleSigV4A:
|
||||
signer := v4a.NewSigner(func(options *v4a.SignerOptions) {
|
||||
options.DisableURIPathEscaping = true
|
||||
options.LogSigning = true
|
||||
options.Logger = logging.NewStandardLogger(os.Stdout)
|
||||
})
|
||||
|
||||
credAdapter := v4a.SymmetricCredentialAdaptor{
|
||||
|
@ -423,13 +419,16 @@ func (c *Center) checkSign(authHeader *AuthHeader, box *accessbox.Box, request *
|
|||
return fmt.Errorf("failed to derive assymetric key from credentials: %w", err)
|
||||
}
|
||||
|
||||
if authHeader.IsPresigned {
|
||||
if err = checkPresignedDate(authHeader, signatureDateTime); err != nil {
|
||||
return err
|
||||
}
|
||||
if !authHeader.IsPresigned {
|
||||
return signer.VerifySignature(creds, request, authHeader.PayloadHash, authHeader.Service,
|
||||
strings.Split(authHeader.Region, ","), signatureDateTime, authHeader.Signature)
|
||||
}
|
||||
|
||||
return signer.VerifySignature(creds, request, authHeader.PayloadHash, authHeader.Service,
|
||||
if err = checkPresignedDate(authHeader, signatureDateTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return signer.VerifyPresigned(creds, request, authHeader.PayloadHash, authHeader.Service,
|
||||
strings.Split(authHeader.Region, ","), signatureDateTime, authHeader.Signature)
|
||||
default:
|
||||
return fmt.Errorf("invalid preamble: %s", authHeader.Preamble)
|
||||
|
|
|
@ -35,6 +35,7 @@ func TestAuthHeaderParse(t *testing.T) {
|
|||
Signature: "2811ccb9e242f41426738fb1f",
|
||||
SignedFields: []string{"host", "x-amz-content-sha256", "x-amz-date"},
|
||||
Date: "20210809",
|
||||
Preamble: signaturePreambleSigV4,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ type PresignData struct {
|
|||
Region string
|
||||
Lifetime time.Duration
|
||||
SignTime time.Time
|
||||
Headers map[string]string
|
||||
}
|
||||
|
||||
// PresignRequest forms pre-signed request to access objects without aws credentials.
|
||||
|
@ -38,8 +39,10 @@ func PresignRequest(creds *credentials.Credentials, reqData RequestData, presign
|
|||
return nil, fmt.Errorf("failed to create new request: %w", err)
|
||||
}
|
||||
|
||||
for k, v := range presignData.Headers {
|
||||
req.Header.Set(k, v) // maybe we should filter system header (or keep responsibility on caller)
|
||||
}
|
||||
req.Header.Set(AmzDate, presignData.SignTime.Format("20060102T150405Z"))
|
||||
req.Header.Set(ContentTypeHdr, "text/plain")
|
||||
|
||||
signer := v4.NewSigner(creds)
|
||||
signer.DisableURIPathEscaping = true
|
||||
|
@ -59,8 +62,11 @@ func PresignRequestV4a(credProvider credentialsv2.StaticCredentialsProvider, req
|
|||
return nil, fmt.Errorf("failed to create new request: %w", err)
|
||||
}
|
||||
|
||||
for k, v := range presignData.Headers {
|
||||
req.Header.Set(k, v) // maybe we should filter system header (or keep responsibility on caller)
|
||||
}
|
||||
|
||||
req.Header.Set(AmzDate, presignData.SignTime.Format("20060102T150405Z"))
|
||||
req.Header.Set(ContentTypeHdr, "text/plain")
|
||||
req.Header.Set(AmzExpires, strconv.Itoa(int(presignData.Lifetime.Seconds())))
|
||||
|
||||
signer := v4a.NewSigner(func(options *v4a.SignerOptions) {
|
||||
|
|
|
@ -75,6 +75,9 @@ func TestCheckSign(t *testing.T) {
|
|||
Region: "spb",
|
||||
Lifetime: 10 * time.Minute,
|
||||
SignTime: time.Now().UTC(),
|
||||
Headers: map[string]string{
|
||||
ContentTypeHdr: "text/plain",
|
||||
},
|
||||
}
|
||||
|
||||
req, err := PresignRequest(awsCreds, reqData, presignData)
|
||||
|
@ -119,11 +122,16 @@ func TestCheckSignV4a(t *testing.T) {
|
|||
Region: "spb",
|
||||
Lifetime: 10 * time.Minute,
|
||||
SignTime: time.Now().UTC(),
|
||||
Headers: map[string]string{
|
||||
ContentTypeHdr: "text/plain",
|
||||
},
|
||||
}
|
||||
|
||||
req, err := PresignRequestV4a(awsCreds, reqData, presignData)
|
||||
require.NoError(t, err)
|
||||
|
||||
req.Header.Set(ContentTypeHdr, "text/plain")
|
||||
|
||||
expBox := &accessbox.Box{
|
||||
Gate: &accessbox.GateData{
|
||||
SecretKey: secretKey,
|
||||
|
@ -170,9 +178,7 @@ func TestPresignRequestV4a(t *testing.T) {
|
|||
|
||||
req, err := http.NewRequest("GET", "http://localhost:8084/bucket/object", nil)
|
||||
require.NoError(t, err)
|
||||
//req.Header.Set(AmzRegionSet, strings.Join(regionSet, ","))
|
||||
//req.Header.Set(AmzDate, signingTime.Format("20060102T150405Z"))
|
||||
//req.Header.Set(AmzAlgorithm, signaturePreambleSigV4A)
|
||||
req.Header.Set(AmzExpires, "600")
|
||||
|
||||
presignedURL, hdr, err := signer.PresignHTTP(req.Context(), creds, req, "", service, regionSet, signingTime)
|
||||
require.NoError(t, err)
|
||||
|
@ -184,7 +190,10 @@ func TestPresignRequestV4a(t *testing.T) {
|
|||
|
||||
r, err := http.NewRequest("GET", presignedURL, nil)
|
||||
require.NoError(t, err)
|
||||
query := r.URL.Query()
|
||||
query.Del(AmzSignature)
|
||||
r.URL.RawQuery = query.Encode()
|
||||
|
||||
err = signer.VerifySignature(creds, r, "", service, regionSet, signingTime, signature)
|
||||
err = signer.VerifyPresigned(creds, r, "", service, regionSet, signingTime, signature)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
|
|
@ -202,6 +202,15 @@ func (s *Signer) SignHTTP(ctx context.Context, credentials Credentials, r *http.
|
|||
|
||||
// VerifySignature checks sigv4a.
|
||||
func (s *Signer) VerifySignature(credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, signature string, optFns ...func(*SignerOptions)) error {
|
||||
return s.verifySignature(credentials, r, payloadHash, service, regionSet, signingTime, signature, false, optFns...)
|
||||
}
|
||||
|
||||
// VerifyPresigned checks sigv4a.
|
||||
func (s *Signer) VerifyPresigned(credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, signature string, optFns ...func(*SignerOptions)) error {
|
||||
return s.verifySignature(credentials, r, payloadHash, service, regionSet, signingTime, signature, true, optFns...)
|
||||
}
|
||||
|
||||
func (s *Signer) verifySignature(credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, signature string, isPresigned bool, optFns ...func(*SignerOptions)) error {
|
||||
options := s.options
|
||||
for _, fn := range optFns {
|
||||
fn(&options)
|
||||
|
@ -214,6 +223,7 @@ func (s *Signer) VerifySignature(credentials Credentials, r *http.Request, paylo
|
|||
RegionSet: regionSet,
|
||||
Credentials: credentials,
|
||||
Time: signingTime.UTC(),
|
||||
IsPreSign: isPresigned,
|
||||
DisableHeaderHoisting: options.DisableHeaderHoisting,
|
||||
DisableURIPathEscaping: options.DisableURIPathEscaping,
|
||||
}
|
||||
|
@ -465,11 +475,6 @@ func (s *httpSigner) buildCanonicalHeaders(host string, rule v4Internal.Rule, he
|
|||
continue // ignored header
|
||||
}
|
||||
|
||||
if strings.EqualFold(k, contentLengthHeader) {
|
||||
// prevent signing already handled content-length header.
|
||||
continue
|
||||
}
|
||||
|
||||
lowerCaseKey := strings.ToLower(k)
|
||||
if _, ok := signed[lowerCaseKey]; ok {
|
||||
// include additional values
|
||||
|
|
Loading…
Reference in a new issue