From 53cf4f342fa438c493a5e67e59e1ef10c4e56d3b Mon Sep 17 00:00:00 2001 From: jonaustin09 Date: Wed, 30 Aug 2023 23:21:09 +0400 Subject: [PATCH] feat: Added more integration test cases for the authentication and md5 checker --- integration/action-tests.go | 8 + integration/tests.go | 234 ++++++++++++++++++++++++++++ s3api/middlewares/authentication.go | 8 +- 3 files changed, 246 insertions(+), 4 deletions(-) diff --git a/integration/action-tests.go b/integration/action-tests.go index 6721076..c3ea1b5 100644 --- a/integration/action-tests.go +++ b/integration/action-tests.go @@ -12,6 +12,14 @@ func TestAuthentication(s *S3Conf) { Authentication_credentials_invalid_date(s) Authentication_credentials_future_date(s) Authentication_credentials_past_date(s) + Authentication_credentials_non_existing_access_key(s) + Authentication_invalid_signed_headers(s) + Authentication_missing_date_header(s) + Authentication_invalid_date_header(s) + Authentication_date_mismatch(s) + Authentication_incorrect_payload_hash(s) + Authentication_incorrect_md5(s) + Authentication_signature_error_incorrect_secret_key(s) } func TestCreateBucket(s *S3Conf) { diff --git a/integration/tests.go b/integration/tests.go index ce9c5f1..30d12bd 100644 --- a/integration/tests.go +++ b/integration/tests.go @@ -392,6 +392,240 @@ func Authentication_credentials_past_date(s *S3Conf) { }) } +func Authentication_credentials_non_existing_access_key(s *S3Conf) { + testName := "Authentication_credentials_non_existing_access_key" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + authHdr := req.Header.Get("Authorization") + regExp := regexp.MustCompile("Credential=([^/]+)") + hdr := regExp.ReplaceAllString(authHdr, "Credential=a_rarely_existing_access_key_id_a7s86df78as6df89790a8sd7f") + req.Header.Set("Authorization", hdr) + + client := http.Client{ + Timeout: shortTimeout, + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidAccessKeyID)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_invalid_signed_headers(s *S3Conf) { + testName := "Authentication_invalid_signed_headers" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + authHdr := req.Header.Get("Authorization") + regExp := regexp.MustCompile("SignedHeaders=[^,]+,") + hdr := regExp.ReplaceAllString(authHdr, "SignedHeaders-host;x-amz-content-sha256;x-amz-date,") + req.Header.Set("Authorization", hdr) + + client := http.Client{ + Timeout: shortTimeout, + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_missing_date_header(s *S3Conf) { + testName := "Authentication_missing_date_header" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + req.Header.Set("X-Amz-Date", "") + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMissingDateHeader)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_invalid_date_header(s *S3Conf) { + testName := "Authentication_invalid_date_header" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + req.Header.Set("X-Amz-Date", "03032006") + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMalformedDate)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_date_mismatch(s *S3Conf) { + testName := "Authentication_date_mismatch" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + req.Header.Set("X-Amz-Date", "20220830T095525Z") + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_incorrect_payload_hash(s *S3Conf) { + testName := "Authentication_incorrect_payload_hash" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + req.Header.Set("X-Amz-Content-Sha256", "7sa6df576dsa5f675sad67f") + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrContentSHA256Mismatch)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_incorrect_md5(s *S3Conf) { + testName := "Authentication_incorrect_md5" + authHandler(s, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + + req.Header.Set("Content-Md5", "sadfasdf87sad6f87==") + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidDigest)); err != nil { + return err + } + + return nil + }) +} + +func Authentication_signature_error_incorrect_secret_key(s *S3Conf) { + testName := "Authentication_signature_error_incorrect_secret_key" + cfg := *s + cfg.awsSecret = s.awsSecret + "a" + authHandler(&cfg, &authConfig{ + testName: testName, + path: "my-bucket", + method: http.MethodGet, + body: nil, + service: "s3", + date: time.Now(), + }, func(req *http.Request) error { + client := http.Client{ + Timeout: shortTimeout, + } + + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDoesNotMatch)); err != nil { + return err + } + + return nil + }) +} + func CreateBucket_invalid_bucket_name(s *S3Conf) { testName := "CreateBucket_invalid_bucket_name" runF(testName) diff --git a/s3api/middlewares/authentication.go b/s3api/middlewares/authentication.go index dc0efe1..001369b 100644 --- a/s3api/middlewares/authentication.go +++ b/s3api/middlewares/authentication.go @@ -124,16 +124,16 @@ func VerifyV4Signature(root RootUserConfig, iam auth.IAMService, logger s3log.Au return controllers.SendResponse(ctx, s3err.GetAPIError(s3err.ErrMissingDateHeader), &controllers.MetaOpts{Logger: logger}) } - if date[:8] != creds[1] { - return controllers.SendResponse(ctx, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch), &controllers.MetaOpts{Logger: logger}) - } - // Parse the date and check the date validity tdate, err := time.Parse(iso8601Format, date) if err != nil { return controllers.SendResponse(ctx, s3err.GetAPIError(s3err.ErrMalformedDate), &controllers.MetaOpts{Logger: logger}) } + if date[:8] != creds[1] { + return controllers.SendResponse(ctx, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch), &controllers.MetaOpts{Logger: logger}) + } + hashPayloadHeader := ctx.Get("X-Amz-Content-Sha256") ok := isSpecialPayload(hashPayloadHeader)