From 97caad75fcc5f48cb2ae4d11a6573052ee9b2417 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Wed, 14 Aug 2024 12:00:59 -0700 Subject: [PATCH 01/10] Default symbol visibility to hidden in static libs too --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f43c289..d31d1602 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,6 @@ cmake_minimum_required(VERSION 3.1) project(aws-c-auth C) -if (POLICY CMP0069) - cmake_policy(SET CMP0069 NEW) # Enable LTO/IPO if available in the compiler, see AwsCFlags -endif() - if (DEFINED CMAKE_PREFIX_PATH) file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) endif() @@ -65,6 +61,7 @@ file(GLOB AUTH_SRC ${AWS_AUTH_ROOT_SRC} ) +aws_set_common_policies() add_library(${PROJECT_NAME} ${LIBTYPE} ${AUTH_HEADERS} ${AUTH_SRC}) aws_set_common_properties(${PROJECT_NAME}) aws_prepare_symbol_visibility_args(${PROJECT_NAME} "AWS_AUTH") From 084868560e6856943a5b906916ab4957e7c61b70 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Mon, 19 Aug 2024 13:18:41 -0700 Subject: [PATCH 02/10] Update required CMake --- CMakeLists.txt | 3 +-- README.md | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d31d1602..8ae7271e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.13) project(aws-c-auth C) if (DEFINED CMAKE_PREFIX_PATH) @@ -61,7 +61,6 @@ file(GLOB AUTH_SRC ${AWS_AUTH_ROOT_SRC} ) -aws_set_common_policies() add_library(${PROJECT_NAME} ${LIBTYPE} ${AUTH_HEADERS} ${AUTH_SRC}) aws_set_common_properties(${PROJECT_NAME}) aws_prepare_symbol_visibility_args(${PROJECT_NAME} "AWS_AUTH") diff --git a/README.md b/README.md index 088feba5..e0241796 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This library is licensed under the Apache 2.0 License. ### Building -CMake 3.1+ is required to build. +CMake 3.13+ is required to build. `` must be an absolute path in the following instructions. @@ -62,7 +62,7 @@ cmake --build aws-c-auth/build --target install ### Testing Certain tests require a specific environment setup in order to run successfully. This may be a specific execution environment (EC2, ECS, etc...) or it may require certain environment variables to be set that configure properties -(often sensitive materials, like keys). Whether or not these tests are enabled is controlled by certain CMAKE +(often sensitive materials, like keys). Whether or not these tests are enabled is controlled by certain CMAKE properties: * AWS_BUILDING_ON_EC2 - indicates real IMDS credentials provider test(s) should run * AWS_BUILDING_ON_ECS - indciates real ECS credentials provider tests(s) should run From cfc025e409b07b8df4613e0fe22f167ae74797c5 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 23 Aug 2024 12:13:35 -0700 Subject: [PATCH 03/10] Update CacheCredentialsProvider Refresh Time to 5 Minutes before Expiry (#247) --- source/credentials_provider_cached.c | 4 +++- tests/credentials_provider_sts_tests.c | 13 ++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/source/credentials_provider_cached.c b/source/credentials_provider_cached.c index 300794f1..092a2c7f 100644 --- a/source/credentials_provider_cached.c +++ b/source/credentials_provider_cached.c @@ -20,7 +20,7 @@ AWS_STATIC_STRING_FROM_LITERAL(s_credential_expiration_env_var, "AWS_CREDENTIAL_ */ -#define REFRESH_CREDENTIALS_EARLY_DURATION_SECONDS 10 +#define REFRESH_CREDENTIALS_EARLY_DURATION_SECONDS 60 * 5 /* 5 minutes */ struct aws_credentials_provider_cached { struct aws_credentials_provider *source; @@ -120,6 +120,8 @@ static void s_cached_credentials_provider_get_credentials_async_callback( AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL); + } else { + next_refresh_time_in_ns = high_res_now; } } } diff --git a/tests/credentials_provider_sts_tests.c b/tests/credentials_provider_sts_tests.c index 7bc5012a..cee07e8d 100644 --- a/tests/credentials_provider_sts_tests.c +++ b/tests/credentials_provider_sts_tests.c @@ -2078,9 +2078,9 @@ static int s_credentials_provider_sts_cache_expiration_conflict(struct aws_alloc s_tester.mocked_requests[0].body.len); /* advance each time to a little before expiration, verify we get creds with the same expiration */ - uint64_t eight_hundred_seconds_in_ns = aws_timestamp_convert(800, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL); - mock_aws_set_system_time(eight_hundred_seconds_in_ns); - mock_aws_set_high_res_time(HIGH_RES_BASE_TIME_NS + eight_hundred_seconds_in_ns); + uint64_t before_expiration_time = aws_timestamp_convert(599, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL); + mock_aws_set_system_time(before_expiration_time); + mock_aws_set_high_res_time(HIGH_RES_BASE_TIME_NS + before_expiration_time); s_cleanup_creds_callback_data(); @@ -2091,10 +2091,9 @@ static int s_credentials_provider_sts_cache_expiration_conflict(struct aws_alloc ASSERT_TRUE(aws_credentials_get_expiration_timepoint_seconds(s_tester.credentials) == 900); /* advance each time to after expiration but before cached provider timeout, verify we get new creds */ - uint64_t nine_hundred_and_one_seconds_in_ns = - aws_timestamp_convert(901, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL); - mock_aws_set_system_time(nine_hundred_and_one_seconds_in_ns); - mock_aws_set_high_res_time(HIGH_RES_BASE_TIME_NS + nine_hundred_and_one_seconds_in_ns); + uint64_t after_expiration_time = aws_timestamp_convert(901, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_NANOS, NULL); + mock_aws_set_system_time(after_expiration_time); + mock_aws_set_high_res_time(HIGH_RES_BASE_TIME_NS + after_expiration_time); s_cleanup_creds_callback_data(); From ce7fc9fc38c2f7db04df8842ecee317bebdc3b3b Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Tue, 3 Sep 2024 13:32:22 -0700 Subject: [PATCH 04/10] add content-sha256 header for presign when the signed_body_value is set to UNSIGNED-PAYLOAD (#248) --- .github/workflows/ci.yml | 2 +- source/aws_signing.c | 17 +++++++++----- tests/CMakeLists.txt | 2 ++ .../v4/post-unsigned-payload/context.json | 13 +++++++++++ .../header-canonical-request.txt | 10 ++++++++ .../header-signature.txt | 1 + .../header-signed-request.txt | 8 +++++++ .../header-string-to-sign.txt | 4 ++++ .../query-canonical-request.txt | 9 ++++++++ .../post-unsigned-payload/query-signature.txt | 1 + .../query-signed-request.txt | 6 +++++ .../query-string-to-sign.txt | 4 ++++ .../v4/post-unsigned-payload/request.txt | 5 ++++ .../v4/post-vanilla/context.json | 2 +- .../post-x-www-form-urlencoded/context.json | 2 +- .../v4a/post-unsigned-payload/context.json | 13 +++++++++++ .../header-canonical-request.txt | 11 +++++++++ .../header-signature.txt | 1 + .../header-signed-request.txt | 9 ++++++++ .../header-string-to-sign.txt | 4 ++++ .../v4a/post-unsigned-payload/public-key.json | 4 ++++ .../query-canonical-request.txt | 9 ++++++++ .../post-unsigned-payload/query-signature.txt | 1 + .../query-signed-request.txt | 6 +++++ .../query-string-to-sign.txt | 4 ++++ .../v4a/post-unsigned-payload/request.txt | 5 ++++ tests/sigv4_signing_tests.c | 23 +++++++++++++++++++ 27 files changed, 167 insertions(+), 9 deletions(-) create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt create mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt create mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 651b3b2b..9abf07d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,7 +6,7 @@ on: - 'main' env: - BUILDER_VERSION: v0.9.62 + BUILDER_VERSION: v0.9.64 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-c-auth diff --git a/source/aws_signing.c b/source/aws_signing.c index fe5610e2..d88ad139 100644 --- a/source/aws_signing.c +++ b/source/aws_signing.c @@ -1336,10 +1336,17 @@ static int s_build_canonical_stable_header_list( } } - /* - * x-amz-content-sha256 (optional) - */ - if (state->config.signed_body_header == AWS_SBHT_X_AMZ_CONTENT_SHA256) { + /* NOTE: Update MAX_AUTHORIZATION_HEADER_COUNT if more headers added */ + } + + /* + * x-amz-content-sha256 (optional) + */ + if (state->config.signed_body_header == AWS_SBHT_X_AMZ_CONTENT_SHA256) { + if (state->config.signature_type == AWS_ST_HTTP_REQUEST_HEADERS || + (state->config.signature_type == AWS_ST_HTTP_REQUEST_QUERY_PARAMS && + aws_byte_cursor_eq(&state->config.signed_body_value, &g_aws_signed_body_value_unsigned_payload))) { + /* Add the x-amz-content-sha256 header for UNSIGNED-PAYLOAD when signing via query params as well. */ if (s_add_authorization_header( state, stable_header_list, @@ -1349,8 +1356,6 @@ static int s_build_canonical_stable_header_list( return AWS_OP_ERR; } } - - /* NOTE: Update MAX_AUTHORIZATION_HEADER_COUNT if more headers added */ } *out_required_capacity += aws_array_list_length(stable_header_list) * 2; /* ':' + '\n' per header */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ea81c741..40235cf8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -236,6 +236,7 @@ add_test_case(sigv4a_post_header_value_case_test) add_test_case(sigv4a_post_vanilla_test) add_test_case(sigv4a_post_vanilla_empty_query_value_test) add_test_case(sigv4a_post_vanilla_query_test) +add_test_case(sigv4a_post_unsigned_payload_test) add_test_case(sigv4a_post_x_www_form_urlencoded_test) add_test_case(sigv4a_post_x_www_form_urlencoded_parameters_test) add_test_case(sigv4a_post_sts_header_after_test) @@ -274,6 +275,7 @@ add_test_case(sigv4_post_header_key_sort_test) add_test_case(sigv4_post_header_value_case_test) add_test_case(sigv4_post_vanilla_test) add_test_case(sigv4_post_vanilla_empty_query_value_test) +add_test_case(sigv4_post_unsigned_payload_test) add_test_case(sigv4_post_vanilla_query_test) add_test_case(sigv4_post_x_www_form_urlencoded_test) add_test_case(sigv4_post_x_www_form_urlencoded_parameters_test) diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json b/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json new file mode 100644 index 00000000..fb94ba83 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json @@ -0,0 +1,13 @@ +{ + "credentials": { + "access_key_id": "AKIDEXAMPLE", + "secret_access_key": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" + }, + "expiration_in_seconds": 3600, + "normalize": true, + "region": "us-east-1", + "service": "service", + "sign_body": true, + "signed_body_value": "UNSIGNED-PAYLOAD", + "timestamp": "2015-08-30T12:36:00Z" +} diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt new file mode 100644 index 00000000..680f2925 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt @@ -0,0 +1,10 @@ +POST +/ + +content-length:13 +host:example.amazonaws.com +x-amz-content-sha256:UNSIGNED-PAYLOAD +x-amz-date:20150830T123600Z + +content-length;host;x-amz-content-sha256;x-amz-date +UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt new file mode 100644 index 00000000..18bfb894 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt @@ -0,0 +1 @@ +9fb60e8938d2178a7d63b49e055d1e65d8f6226f38846e8e0293bf43ce29050c \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt new file mode 100644 index 00000000..b29935e2 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt @@ -0,0 +1,8 @@ +POST / HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 +X-Amz-Date:20150830T123600Z +x-amz-content-sha256:UNSIGNED-PAYLOAD +Authorization:AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-length;host;x-amz-content-sha256;x-amz-date, Signature=9fb60e8938d2178a7d63b49e055d1e65d8f6226f38846e8e0293bf43ce29050c + +Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt new file mode 100644 index 00000000..cce856f6 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt @@ -0,0 +1,4 @@ +AWS4-HMAC-SHA256 +20150830T123600Z +20150830/us-east-1/service/aws4_request +9dd145dbd195542d88539477304a02796be6488c02842b4fc1b907203adc8663 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt new file mode 100644 index 00000000..de88b92d --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt @@ -0,0 +1,9 @@ +POST +/ +X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fus-east-1%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256 +content-length:13 +host:example.amazonaws.com +x-amz-content-sha256:UNSIGNED-PAYLOAD + +content-length;host;x-amz-content-sha256 +UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt new file mode 100644 index 00000000..f8a2c1a6 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt @@ -0,0 +1 @@ +d5b951b200c7f96f239466b3e1978083ccd08678d4aea2b0bebaa6b2cf3d8c13 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt new file mode 100644 index 00000000..3b977244 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt @@ -0,0 +1,6 @@ +POST /?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fus-east-1%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256&X-Amz-Expires=3600&X-Amz-Signature=d5b951b200c7f96f239466b3e1978083ccd08678d4aea2b0bebaa6b2cf3d8c13 HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 +x-amz-content-sha256:UNSIGNED-PAYLOAD + +Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt new file mode 100644 index 00000000..eaa46be5 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt @@ -0,0 +1,4 @@ +AWS4-HMAC-SHA256 +20150830T123600Z +20150830/us-east-1/service/aws4_request +24b3d8a2ee4f76884e0b2bedfaeb8f4feca93e09d9e53b7d13bc040efd106329 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt new file mode 100644 index 00000000..4b107d53 --- /dev/null +++ b/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt @@ -0,0 +1,5 @@ +POST / HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 + +Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-vanilla/context.json b/tests/aws-signing-test-suite/v4/post-vanilla/context.json index 0468d800..45771c75 100644 --- a/tests/aws-signing-test-suite/v4/post-vanilla/context.json +++ b/tests/aws-signing-test-suite/v4/post-vanilla/context.json @@ -9,4 +9,4 @@ "service": "service", "sign_body": false, "timestamp": "2015-08-30T12:36:00Z" -} \ No newline at end of file +} diff --git a/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json b/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json index 0db1df10..fc4bce6d 100644 --- a/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json +++ b/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json @@ -9,4 +9,4 @@ "service": "service", "sign_body": true, "timestamp": "2015-08-30T12:36:00Z" -} \ No newline at end of file +} diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json new file mode 100644 index 00000000..fb94ba83 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json @@ -0,0 +1,13 @@ +{ + "credentials": { + "access_key_id": "AKIDEXAMPLE", + "secret_access_key": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" + }, + "expiration_in_seconds": 3600, + "normalize": true, + "region": "us-east-1", + "service": "service", + "sign_body": true, + "signed_body_value": "UNSIGNED-PAYLOAD", + "timestamp": "2015-08-30T12:36:00Z" +} diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt new file mode 100644 index 00000000..073ad369 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt @@ -0,0 +1,11 @@ +POST +/ + +content-length:13 +host:example.amazonaws.com +x-amz-content-sha256:UNSIGNED-PAYLOAD +x-amz-date:20150830T123600Z +x-amz-region-set:us-east-1 + +content-length;host;x-amz-content-sha256;x-amz-date;x-amz-region-set +UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt new file mode 100644 index 00000000..ce28747f --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt @@ -0,0 +1 @@ +3046022100aa754cb9eca1113d88f54d83dc8635b6dd9b0f362e5e6c79c82da930521feb70022100c7f572b03542548c0c66eae6ff77202a175c923219fa413d7619d298618016c3 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt new file mode 100644 index 00000000..d04efcb2 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt @@ -0,0 +1,9 @@ +POST / HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 +X-Amz-Date:20150830T123600Z +X-Amz-Region-Set:us-east-1 +x-amz-content-sha256:UNSIGNED-PAYLOAD +Authorization:AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=content-length;host;x-amz-content-sha256;x-amz-date;x-amz-region-set, Signature=3044022076c0a0e1ec8d3e40dd3d3f9c395c30e9ba7552096b4d8c34596646df2b665c6c0220615a2b2132265e969088895332db7f9b6c9daa957b42a9047d94e392f521d6fb + +Param1=value1 diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt new file mode 100644 index 00000000..0935d114 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt @@ -0,0 +1,4 @@ +AWS4-ECDSA-P256-SHA256 +20150830T123600Z +20150830/service/aws4_request +1aa2f34080974173be96cdbddf2e5df2e48a425c6c3ab6cd770c254aaf4898df \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json new file mode 100644 index 00000000..379dcb21 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json @@ -0,0 +1,4 @@ +{ + "X":"b6618f6a65740a99e650b33b6b4b5bd0d43b176d721a3edfea7e7d2d56d936b1", + "Y":"865ed22a7eadc9c5cb9d2cbaca1b3699139fedc5043dc6661864218330c8e518" +} diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt new file mode 100644 index 00000000..be03e0c4 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt @@ -0,0 +1,9 @@ +POST +/ +X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-Expires=3600&X-Amz-Region-Set=us-east-1&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256 +content-length:13 +host:example.amazonaws.com +x-amz-content-sha256:UNSIGNED-PAYLOAD + +content-length;host;x-amz-content-sha256 +UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt new file mode 100644 index 00000000..543ab076 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt @@ -0,0 +1 @@ +304402203e661f9bc2dc93d9c858e08018d79ad36055eaae449d81321773df4df92d367202204064dfbaec5b2e2860d36b6d11d4eda90b18ff62c8ac14f90e288ef37bcfe15e \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt new file mode 100644 index 00000000..a31db27b --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt @@ -0,0 +1,6 @@ +POST /?X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256&X-Amz-Expires=3600&X-Amz-Region-Set=us-east-1&X-Amz-Signature=3045022100b32d20d894fb447713b4ba31a7983b04a7c7551b597dbd0b5478af0cc98ee33802201b4d03ad196f18baa962102b166eec484819c34be71a56e10b494146ebe043cc HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 +x-amz-content-sha256:UNSIGNED-PAYLOAD + +Param1=value1 diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt new file mode 100644 index 00000000..0767ddc9 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt @@ -0,0 +1,4 @@ +AWS4-ECDSA-P256-SHA256 +20150830T123600Z +20150830/service/aws4_request +41fc1ad3ae67d78001e68d2e0e3149bd0f6f45f44ae68b3e615c2ee4183aa2d1 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt new file mode 100644 index 00000000..4b107d53 --- /dev/null +++ b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt @@ -0,0 +1,5 @@ +POST / HTTP/1.1 +Host:example.amazonaws.com +Content-Length:13 + +Param1=value1 diff --git a/tests/sigv4_signing_tests.c b/tests/sigv4_signing_tests.c index 3437c03a..7076561d 100644 --- a/tests/sigv4_signing_tests.c +++ b/tests/sigv4_signing_tests.c @@ -209,6 +209,7 @@ struct v4_test_context { struct aws_credentials *credentials; bool should_normalize; bool should_sign_body; + struct aws_string *signed_body_value; uint64_t expiration_in_seconds; struct aws_input_stream *payload_stream; struct aws_ecc_key_pair *signing_key; @@ -242,6 +243,7 @@ static void s_v4_test_context_clean_up(struct v4_test_context *context) { aws_string_destroy(context->region_config); aws_string_destroy(context->service); aws_string_destroy(context->timestamp); + aws_string_destroy(context->signed_body_value); aws_credentials_release(context->credentials); aws_mutex_clean_up(&context->lock); @@ -265,6 +267,7 @@ AWS_STATIC_STRING_FROM_LITERAL(s_service_name, "service"); AWS_STATIC_STRING_FROM_LITERAL(s_timestamp_name, "timestamp"); AWS_STATIC_STRING_FROM_LITERAL(s_normalize_name, "normalize"); AWS_STATIC_STRING_FROM_LITERAL(s_body_name, "sign_body"); +AWS_STATIC_STRING_FROM_LITERAL(s_signed_body_value_name, "signed_body_value"); AWS_STATIC_STRING_FROM_LITERAL(s_expiration_name, "expiration_in_seconds"); AWS_STATIC_STRING_FROM_LITERAL(s_omit_token_name, "omit_session_token"); @@ -385,6 +388,20 @@ static int s_v4_test_context_parse_context_file(struct v4_test_context *context) aws_json_value_get_boolean(body_node, &context->should_sign_body); + struct aws_json_value *signed_body_value_node = + aws_json_value_get_from_object(document_root, aws_byte_cursor_from_string(s_signed_body_value_name)); + if (signed_body_value_node != NULL && aws_json_value_is_string(signed_body_value_node)) { + struct aws_byte_cursor signed_body_value_cursor; + /* Optional field. If not set, ignore it. */ + if (aws_json_value_get_string(signed_body_value_node, &signed_body_value_cursor) == AWS_OP_ERR) { + goto done; + } + context->signed_body_value = aws_string_new_from_cursor(context->allocator, &signed_body_value_cursor); + if (context->signed_body_value == NULL) { + goto done; + } + } + struct aws_json_value *expiration_node = aws_json_value_get_from_object(document_root, aws_byte_cursor_from_string(s_expiration_name)); if (expiration_node == NULL || !aws_json_value_is_number(expiration_node)) { @@ -587,6 +604,10 @@ static int s_v4_test_context_init_signing_config( } else { context->config->signed_body_value = g_aws_signed_body_value_empty_sha256; } + if (context->signed_body_value) { + /* Override the signed body value */ + context->config->signed_body_value = aws_byte_cursor_from_string(context->signed_body_value); + } context->config->credentials = context->credentials; context->config->expiration_in_seconds = context->expiration_in_seconds; @@ -1407,6 +1428,7 @@ DECLARE_SIGV4A_TEST_SUITE_CASE(post_header_value_case, "post-header-value-case") DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla, "post-vanilla"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla_empty_query_value, "post-vanilla-empty-query-value"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla_query, "post-vanilla-query"); +DECLARE_SIGV4A_TEST_SUITE_CASE(post_unsigned_payload, "post-unsigned-payload"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_x_www_form_urlencoded, "post-x-www-form-urlencoded"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_x_www_form_urlencoded_parameters, "post-x-www-form-urlencoded-parameters"); DECLARE_SIGV4A_TEST_SUITE_CASE(get_vanilla_with_session_token, "get-vanilla-with-session-token"); @@ -1470,6 +1492,7 @@ DECLARE_SIGV4_TEST_SUITE_CASE(post_header_value_case, "post-header-value-case"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla, "post-vanilla"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla_empty_query_value, "post-vanilla-empty-query-value"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla_query, "post-vanilla-query"); +DECLARE_SIGV4_TEST_SUITE_CASE(post_unsigned_payload, "post-unsigned-payload"); DECLARE_SIGV4_TEST_SUITE_CASE(post_x_www_form_urlencoded, "post-x-www-form-urlencoded"); DECLARE_SIGV4_TEST_SUITE_CASE(post_x_www_form_urlencoded_parameters, "post-x-www-form-urlencoded-parameters"); DECLARE_SIGV4_TEST_SUITE_CASE(get_vanilla_with_session_token, "get-vanilla-with-session-token"); From f8fcf2d5c6e39a1530615b188822f513647ab66f Mon Sep 17 00:00:00 2001 From: Dengke Tang Date: Thu, 5 Sep 2024 14:52:30 -0700 Subject: [PATCH 05/10] vpc-lattice-svcs specific presign (#249) --- source/aws_signing.c | 42 ++++++++++++++----- tests/CMakeLists.txt | 2 - .../v4/post-unsigned-payload/context.json | 13 ------ .../header-canonical-request.txt | 10 ----- .../header-signature.txt | 1 - .../header-signed-request.txt | 8 ---- .../header-string-to-sign.txt | 4 -- .../query-canonical-request.txt | 9 ---- .../post-unsigned-payload/query-signature.txt | 1 - .../query-signed-request.txt | 6 --- .../query-string-to-sign.txt | 4 -- .../v4/post-unsigned-payload/request.txt | 5 --- .../v4/post-vanilla/context.json | 2 +- .../post-x-www-form-urlencoded/context.json | 2 +- .../v4a/post-unsigned-payload/context.json | 13 ------ .../header-canonical-request.txt | 11 ----- .../header-signature.txt | 1 - .../header-signed-request.txt | 9 ---- .../header-string-to-sign.txt | 4 -- .../v4a/post-unsigned-payload/public-key.json | 4 -- .../query-canonical-request.txt | 9 ---- .../post-unsigned-payload/query-signature.txt | 1 - .../query-signed-request.txt | 6 --- .../query-string-to-sign.txt | 4 -- .../v4a/post-unsigned-payload/request.txt | 5 --- tests/sigv4_signing_tests.c | 23 ---------- 26 files changed, 33 insertions(+), 166 deletions(-) delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt delete mode 100644 tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt delete mode 100644 tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt diff --git a/source/aws_signing.c b/source/aws_signing.c index d88ad139..a51f80be 100644 --- a/source/aws_signing.c +++ b/source/aws_signing.c @@ -1336,17 +1336,10 @@ static int s_build_canonical_stable_header_list( } } - /* NOTE: Update MAX_AUTHORIZATION_HEADER_COUNT if more headers added */ - } - - /* - * x-amz-content-sha256 (optional) - */ - if (state->config.signed_body_header == AWS_SBHT_X_AMZ_CONTENT_SHA256) { - if (state->config.signature_type == AWS_ST_HTTP_REQUEST_HEADERS || - (state->config.signature_type == AWS_ST_HTTP_REQUEST_QUERY_PARAMS && - aws_byte_cursor_eq(&state->config.signed_body_value, &g_aws_signed_body_value_unsigned_payload))) { - /* Add the x-amz-content-sha256 header for UNSIGNED-PAYLOAD when signing via query params as well. */ + /* + * x-amz-content-sha256 (optional) + */ + if (state->config.signed_body_header == AWS_SBHT_X_AMZ_CONTENT_SHA256) { if (s_add_authorization_header( state, stable_header_list, @@ -1356,6 +1349,22 @@ static int s_build_canonical_stable_header_list( return AWS_OP_ERR; } } + + /* NOTE: Update MAX_AUTHORIZATION_HEADER_COUNT if more headers added */ + } else if ( + state->config.signature_type == AWS_ST_HTTP_REQUEST_QUERY_PARAMS && + aws_byte_cursor_eq_c_str(&state->config.service, "vpc-lattice-svcs")) { + /* NOTES: TEMPORAY WORKAROUND FOR VPC Lattice. SHALL BE REMOVED IN NEAR FUTURE */ + /* Add unsigned payload as `x-amz-content-sha256` header to the canonical request when signing through query + * params. */ + if (s_add_authorization_header( + state, + stable_header_list, + out_required_capacity, + s_amz_content_sha256_header_name, + g_aws_signed_body_value_unsigned_payload)) { + return AWS_OP_ERR; + } } *out_required_capacity += aws_array_list_length(stable_header_list) * 2; /* ':' + '\n' per header */ @@ -1518,6 +1527,17 @@ static int s_build_canonical_payload(struct aws_signing_state_aws *state) { struct aws_hash *hash = NULL; int result = AWS_OP_ERR; + if (state->config.signature_type == AWS_ST_HTTP_REQUEST_QUERY_PARAMS && + aws_byte_cursor_eq_c_str(&state->config.service, "vpc-lattice-svcs")) { + /* NOTES: TEMPORAY WORKAROUND FOR VPC Lattice. SHALL BE REMOVED IN NEAR FUTURE */ + /* ALWAYS USE UNSIGNED-PAYLOAD FOR VPC Lattice. */ + if (aws_byte_buf_append_dynamic(payload_hash_buffer, &g_aws_signed_body_value_unsigned_payload) == + AWS_OP_SUCCESS) { + result = AWS_OP_SUCCESS; + } + goto on_cleanup; + } + if (state->config.signed_body_value.len == 0) { /* No value provided by user, so we must calculate it */ hash = aws_sha256_new(allocator); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 40235cf8..ea81c741 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -236,7 +236,6 @@ add_test_case(sigv4a_post_header_value_case_test) add_test_case(sigv4a_post_vanilla_test) add_test_case(sigv4a_post_vanilla_empty_query_value_test) add_test_case(sigv4a_post_vanilla_query_test) -add_test_case(sigv4a_post_unsigned_payload_test) add_test_case(sigv4a_post_x_www_form_urlencoded_test) add_test_case(sigv4a_post_x_www_form_urlencoded_parameters_test) add_test_case(sigv4a_post_sts_header_after_test) @@ -275,7 +274,6 @@ add_test_case(sigv4_post_header_key_sort_test) add_test_case(sigv4_post_header_value_case_test) add_test_case(sigv4_post_vanilla_test) add_test_case(sigv4_post_vanilla_empty_query_value_test) -add_test_case(sigv4_post_unsigned_payload_test) add_test_case(sigv4_post_vanilla_query_test) add_test_case(sigv4_post_x_www_form_urlencoded_test) add_test_case(sigv4_post_x_www_form_urlencoded_parameters_test) diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json b/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json deleted file mode 100644 index fb94ba83..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/context.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "credentials": { - "access_key_id": "AKIDEXAMPLE", - "secret_access_key": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" - }, - "expiration_in_seconds": 3600, - "normalize": true, - "region": "us-east-1", - "service": "service", - "sign_body": true, - "signed_body_value": "UNSIGNED-PAYLOAD", - "timestamp": "2015-08-30T12:36:00Z" -} diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt deleted file mode 100644 index 680f2925..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-canonical-request.txt +++ /dev/null @@ -1,10 +0,0 @@ -POST -/ - -content-length:13 -host:example.amazonaws.com -x-amz-content-sha256:UNSIGNED-PAYLOAD -x-amz-date:20150830T123600Z - -content-length;host;x-amz-content-sha256;x-amz-date -UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt deleted file mode 100644 index 18bfb894..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signature.txt +++ /dev/null @@ -1 +0,0 @@ -9fb60e8938d2178a7d63b49e055d1e65d8f6226f38846e8e0293bf43ce29050c \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt deleted file mode 100644 index b29935e2..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-signed-request.txt +++ /dev/null @@ -1,8 +0,0 @@ -POST / HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 -X-Amz-Date:20150830T123600Z -x-amz-content-sha256:UNSIGNED-PAYLOAD -Authorization:AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=content-length;host;x-amz-content-sha256;x-amz-date, Signature=9fb60e8938d2178a7d63b49e055d1e65d8f6226f38846e8e0293bf43ce29050c - -Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt deleted file mode 100644 index cce856f6..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/header-string-to-sign.txt +++ /dev/null @@ -1,4 +0,0 @@ -AWS4-HMAC-SHA256 -20150830T123600Z -20150830/us-east-1/service/aws4_request -9dd145dbd195542d88539477304a02796be6488c02842b4fc1b907203adc8663 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt deleted file mode 100644 index de88b92d..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-canonical-request.txt +++ /dev/null @@ -1,9 +0,0 @@ -POST -/ -X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fus-east-1%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256 -content-length:13 -host:example.amazonaws.com -x-amz-content-sha256:UNSIGNED-PAYLOAD - -content-length;host;x-amz-content-sha256 -UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt deleted file mode 100644 index f8a2c1a6..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signature.txt +++ /dev/null @@ -1 +0,0 @@ -d5b951b200c7f96f239466b3e1978083ccd08678d4aea2b0bebaa6b2cf3d8c13 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt deleted file mode 100644 index 3b977244..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-signed-request.txt +++ /dev/null @@ -1,6 +0,0 @@ -POST /?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fus-east-1%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256&X-Amz-Expires=3600&X-Amz-Signature=d5b951b200c7f96f239466b3e1978083ccd08678d4aea2b0bebaa6b2cf3d8c13 HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 -x-amz-content-sha256:UNSIGNED-PAYLOAD - -Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt deleted file mode 100644 index eaa46be5..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/query-string-to-sign.txt +++ /dev/null @@ -1,4 +0,0 @@ -AWS4-HMAC-SHA256 -20150830T123600Z -20150830/us-east-1/service/aws4_request -24b3d8a2ee4f76884e0b2bedfaeb8f4feca93e09d9e53b7d13bc040efd106329 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt b/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt deleted file mode 100644 index 4b107d53..00000000 --- a/tests/aws-signing-test-suite/v4/post-unsigned-payload/request.txt +++ /dev/null @@ -1,5 +0,0 @@ -POST / HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 - -Param1=value1 diff --git a/tests/aws-signing-test-suite/v4/post-vanilla/context.json b/tests/aws-signing-test-suite/v4/post-vanilla/context.json index 45771c75..0468d800 100644 --- a/tests/aws-signing-test-suite/v4/post-vanilla/context.json +++ b/tests/aws-signing-test-suite/v4/post-vanilla/context.json @@ -9,4 +9,4 @@ "service": "service", "sign_body": false, "timestamp": "2015-08-30T12:36:00Z" -} +} \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json b/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json index fc4bce6d..0db1df10 100644 --- a/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json +++ b/tests/aws-signing-test-suite/v4/post-x-www-form-urlencoded/context.json @@ -9,4 +9,4 @@ "service": "service", "sign_body": true, "timestamp": "2015-08-30T12:36:00Z" -} +} \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json deleted file mode 100644 index fb94ba83..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/context.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "credentials": { - "access_key_id": "AKIDEXAMPLE", - "secret_access_key": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY" - }, - "expiration_in_seconds": 3600, - "normalize": true, - "region": "us-east-1", - "service": "service", - "sign_body": true, - "signed_body_value": "UNSIGNED-PAYLOAD", - "timestamp": "2015-08-30T12:36:00Z" -} diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt deleted file mode 100644 index 073ad369..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-canonical-request.txt +++ /dev/null @@ -1,11 +0,0 @@ -POST -/ - -content-length:13 -host:example.amazonaws.com -x-amz-content-sha256:UNSIGNED-PAYLOAD -x-amz-date:20150830T123600Z -x-amz-region-set:us-east-1 - -content-length;host;x-amz-content-sha256;x-amz-date;x-amz-region-set -UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt deleted file mode 100644 index ce28747f..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signature.txt +++ /dev/null @@ -1 +0,0 @@ -3046022100aa754cb9eca1113d88f54d83dc8635b6dd9b0f362e5e6c79c82da930521feb70022100c7f572b03542548c0c66eae6ff77202a175c923219fa413d7619d298618016c3 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt deleted file mode 100644 index d04efcb2..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-signed-request.txt +++ /dev/null @@ -1,9 +0,0 @@ -POST / HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 -X-Amz-Date:20150830T123600Z -X-Amz-Region-Set:us-east-1 -x-amz-content-sha256:UNSIGNED-PAYLOAD -Authorization:AWS4-ECDSA-P256-SHA256 Credential=AKIDEXAMPLE/20150830/service/aws4_request, SignedHeaders=content-length;host;x-amz-content-sha256;x-amz-date;x-amz-region-set, Signature=3044022076c0a0e1ec8d3e40dd3d3f9c395c30e9ba7552096b4d8c34596646df2b665c6c0220615a2b2132265e969088895332db7f9b6c9daa957b42a9047d94e392f521d6fb - -Param1=value1 diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt deleted file mode 100644 index 0935d114..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/header-string-to-sign.txt +++ /dev/null @@ -1,4 +0,0 @@ -AWS4-ECDSA-P256-SHA256 -20150830T123600Z -20150830/service/aws4_request -1aa2f34080974173be96cdbddf2e5df2e48a425c6c3ab6cd770c254aaf4898df \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json deleted file mode 100644 index 379dcb21..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/public-key.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "X":"b6618f6a65740a99e650b33b6b4b5bd0d43b176d721a3edfea7e7d2d56d936b1", - "Y":"865ed22a7eadc9c5cb9d2cbaca1b3699139fedc5043dc6661864218330c8e518" -} diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt deleted file mode 100644 index be03e0c4..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-canonical-request.txt +++ /dev/null @@ -1,9 +0,0 @@ -POST -/ -X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-Expires=3600&X-Amz-Region-Set=us-east-1&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256 -content-length:13 -host:example.amazonaws.com -x-amz-content-sha256:UNSIGNED-PAYLOAD - -content-length;host;x-amz-content-sha256 -UNSIGNED-PAYLOAD \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt deleted file mode 100644 index 543ab076..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signature.txt +++ /dev/null @@ -1 +0,0 @@ -304402203e661f9bc2dc93d9c858e08018d79ad36055eaae449d81321773df4df92d367202204064dfbaec5b2e2860d36b6d11d4eda90b18ff62c8ac14f90e288ef37bcfe15e \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt deleted file mode 100644 index a31db27b..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-signed-request.txt +++ /dev/null @@ -1,6 +0,0 @@ -POST /?X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&X-Amz-Credential=AKIDEXAMPLE%2F20150830%2Fservice%2Faws4_request&X-Amz-Date=20150830T123600Z&X-Amz-SignedHeaders=content-length%3Bhost%3Bx-amz-content-sha256&X-Amz-Expires=3600&X-Amz-Region-Set=us-east-1&X-Amz-Signature=3045022100b32d20d894fb447713b4ba31a7983b04a7c7551b597dbd0b5478af0cc98ee33802201b4d03ad196f18baa962102b166eec484819c34be71a56e10b494146ebe043cc HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 -x-amz-content-sha256:UNSIGNED-PAYLOAD - -Param1=value1 diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt deleted file mode 100644 index 0767ddc9..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/query-string-to-sign.txt +++ /dev/null @@ -1,4 +0,0 @@ -AWS4-ECDSA-P256-SHA256 -20150830T123600Z -20150830/service/aws4_request -41fc1ad3ae67d78001e68d2e0e3149bd0f6f45f44ae68b3e615c2ee4183aa2d1 \ No newline at end of file diff --git a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt b/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt deleted file mode 100644 index 4b107d53..00000000 --- a/tests/aws-signing-test-suite/v4a/post-unsigned-payload/request.txt +++ /dev/null @@ -1,5 +0,0 @@ -POST / HTTP/1.1 -Host:example.amazonaws.com -Content-Length:13 - -Param1=value1 diff --git a/tests/sigv4_signing_tests.c b/tests/sigv4_signing_tests.c index 7076561d..3437c03a 100644 --- a/tests/sigv4_signing_tests.c +++ b/tests/sigv4_signing_tests.c @@ -209,7 +209,6 @@ struct v4_test_context { struct aws_credentials *credentials; bool should_normalize; bool should_sign_body; - struct aws_string *signed_body_value; uint64_t expiration_in_seconds; struct aws_input_stream *payload_stream; struct aws_ecc_key_pair *signing_key; @@ -243,7 +242,6 @@ static void s_v4_test_context_clean_up(struct v4_test_context *context) { aws_string_destroy(context->region_config); aws_string_destroy(context->service); aws_string_destroy(context->timestamp); - aws_string_destroy(context->signed_body_value); aws_credentials_release(context->credentials); aws_mutex_clean_up(&context->lock); @@ -267,7 +265,6 @@ AWS_STATIC_STRING_FROM_LITERAL(s_service_name, "service"); AWS_STATIC_STRING_FROM_LITERAL(s_timestamp_name, "timestamp"); AWS_STATIC_STRING_FROM_LITERAL(s_normalize_name, "normalize"); AWS_STATIC_STRING_FROM_LITERAL(s_body_name, "sign_body"); -AWS_STATIC_STRING_FROM_LITERAL(s_signed_body_value_name, "signed_body_value"); AWS_STATIC_STRING_FROM_LITERAL(s_expiration_name, "expiration_in_seconds"); AWS_STATIC_STRING_FROM_LITERAL(s_omit_token_name, "omit_session_token"); @@ -388,20 +385,6 @@ static int s_v4_test_context_parse_context_file(struct v4_test_context *context) aws_json_value_get_boolean(body_node, &context->should_sign_body); - struct aws_json_value *signed_body_value_node = - aws_json_value_get_from_object(document_root, aws_byte_cursor_from_string(s_signed_body_value_name)); - if (signed_body_value_node != NULL && aws_json_value_is_string(signed_body_value_node)) { - struct aws_byte_cursor signed_body_value_cursor; - /* Optional field. If not set, ignore it. */ - if (aws_json_value_get_string(signed_body_value_node, &signed_body_value_cursor) == AWS_OP_ERR) { - goto done; - } - context->signed_body_value = aws_string_new_from_cursor(context->allocator, &signed_body_value_cursor); - if (context->signed_body_value == NULL) { - goto done; - } - } - struct aws_json_value *expiration_node = aws_json_value_get_from_object(document_root, aws_byte_cursor_from_string(s_expiration_name)); if (expiration_node == NULL || !aws_json_value_is_number(expiration_node)) { @@ -604,10 +587,6 @@ static int s_v4_test_context_init_signing_config( } else { context->config->signed_body_value = g_aws_signed_body_value_empty_sha256; } - if (context->signed_body_value) { - /* Override the signed body value */ - context->config->signed_body_value = aws_byte_cursor_from_string(context->signed_body_value); - } context->config->credentials = context->credentials; context->config->expiration_in_seconds = context->expiration_in_seconds; @@ -1428,7 +1407,6 @@ DECLARE_SIGV4A_TEST_SUITE_CASE(post_header_value_case, "post-header-value-case") DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla, "post-vanilla"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla_empty_query_value, "post-vanilla-empty-query-value"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_vanilla_query, "post-vanilla-query"); -DECLARE_SIGV4A_TEST_SUITE_CASE(post_unsigned_payload, "post-unsigned-payload"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_x_www_form_urlencoded, "post-x-www-form-urlencoded"); DECLARE_SIGV4A_TEST_SUITE_CASE(post_x_www_form_urlencoded_parameters, "post-x-www-form-urlencoded-parameters"); DECLARE_SIGV4A_TEST_SUITE_CASE(get_vanilla_with_session_token, "get-vanilla-with-session-token"); @@ -1492,7 +1470,6 @@ DECLARE_SIGV4_TEST_SUITE_CASE(post_header_value_case, "post-header-value-case"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla, "post-vanilla"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla_empty_query_value, "post-vanilla-empty-query-value"); DECLARE_SIGV4_TEST_SUITE_CASE(post_vanilla_query, "post-vanilla-query"); -DECLARE_SIGV4_TEST_SUITE_CASE(post_unsigned_payload, "post-unsigned-payload"); DECLARE_SIGV4_TEST_SUITE_CASE(post_x_www_form_urlencoded, "post-x-www-form-urlencoded"); DECLARE_SIGV4_TEST_SUITE_CASE(post_x_www_form_urlencoded_parameters, "post-x-www-form-urlencoded-parameters"); DECLARE_SIGV4_TEST_SUITE_CASE(get_vanilla_with_session_token, "get-vanilla-with-session-token"); From c5de50773c574a1935b0077aa5117271d25737e3 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Fri, 6 Sep 2024 09:24:51 -0700 Subject: [PATCH 06/10] When sourcing credentials from an external process, ignore stderr (#250) **Issue:** If the external process logged to `stderr` during a normal successful run, the credentials would fail to parse. This was happening because the credentials-provider would always combine `stderr` and `stdout` by appending `2>&1` to the external command. Then JSON parsing would fail, due to random lines of logging on `stderr` mixing with valid JSON on `stdout`. **Description of changes:** Instead of redirecting `stderr` to `stdout`, redirect it to `/dev/null`. It would be better to capture `stderr` separately, and display it if the external process fails. But `aws_process_run()` doesn't currently capture `stderr`, and would require a rework to do so. --- source/credentials_provider_process.c | 19 ++++- tests/CMakeLists.txt | 1 + tests/credentials_provider_process_tests.c | 93 +++++++++++----------- 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/source/credentials_provider_process.c b/source/credentials_provider_process.c index d043ff39..a78c661a 100644 --- a/source/credentials_provider_process.c +++ b/source/credentials_provider_process.c @@ -152,7 +152,22 @@ static void s_check_or_get_with_profile_config( } } -static struct aws_byte_cursor s_stderr_redirect_to_stdout = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" 2>&1"); +/* Redirect stderr to /dev/null + * As of Sep 2024, aws_process_run() can only capture stdout, and the + * process's stderr goes into the stderr of the application that launched it. + * Some credentials-processes log to stderr during normal operation. + * To prevent this from polluting the application's stderr, + * we redirect the credential-process's stderr into oblivion. + * + * It would be better to fix aws_process_run() so it captures stderr as well, + * and logging it if the process fails. This is recommended by the SEP: + * > SDKs SHOULD make this error message accessible to the customer. */ +#ifdef _WIN32 +static struct aws_byte_cursor s_stderr_redirect_to_devnull = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" 2> nul"); +#else +static struct aws_byte_cursor s_stderr_redirect_to_devnull = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" 2> /dev/null"); +#endif + static struct aws_string *s_get_command( struct aws_allocator *allocator, const struct aws_credentials_provider_process_options *options) { @@ -190,7 +205,7 @@ static struct aws_string *s_get_command( goto on_finish; } - if (aws_byte_buf_append_dynamic(&command_buf, &s_stderr_redirect_to_stdout)) { + if (aws_byte_buf_append_dynamic(&command_buf, &s_stderr_redirect_to_devnull)) { goto on_finish; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ea81c741..a2f9bf6a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -113,6 +113,7 @@ add_test_case(credentials_provider_process_new_failed) add_test_case(credentials_provider_process_bad_command) add_test_case(credentials_provider_process_incorrect_command_output) add_test_case(credentials_provider_process_basic_success) +add_test_case(credentials_provider_process_success_ignores_stderr) add_test_case(credentials_provider_process_basic_success_from_profile_provider) add_test_case(credentials_provider_process_basic_success_cached) diff --git a/tests/credentials_provider_process_tests.c b/tests/credentials_provider_process_tests.c index c761ea8e..57b00634 100644 --- a/tests/credentials_provider_process_tests.c +++ b/tests/credentials_provider_process_tests.c @@ -144,6 +144,28 @@ AWS_STATIC_STRING_FROM_LITERAL( "\"Expiration\":\"2020-02-25T06:03:31Z\"}'"); #endif +#ifdef _WIN32 +AWS_STATIC_STRING_FROM_LITERAL( + s_test_command_with_logging_on_stderr, + "(" + "echo Logging on stderr >&2" + " && " + "echo {\"Version\": 1, \"AccessKeyId\": \"AccessKey123\", " + "\"SecretAccessKey\": \"SecretAccessKey321\", \"SessionToken\":\"TokenSuccess\", " + "\"Expiration\":\"2020-02-25T06:03:31Z\"}" + ")"); +#else +AWS_STATIC_STRING_FROM_LITERAL( + s_test_command_with_logging_on_stderr, + "(" + "echo 'Logging on stderr' >&2" + " && " + "echo '{\"Version\": 1, \"AccessKeyId\": \"AccessKey123\", " + "\"SecretAccessKey\": \"SecretAccessKey321\", \"SessionToken\":\"TokenSuccess\", " + "\"Expiration\":\"2020-02-25T06:03:31Z\"}'" + ")"); +#endif + AWS_STATIC_STRING_FROM_LITERAL(s_bad_test_command, "/i/dont/know/what/is/this/command"); AWS_STATIC_STRING_FROM_LITERAL(s_bad_command_output, "echo \"Hello, World!\""); @@ -262,15 +284,14 @@ static int s_credentials_provider_process_new_failed(struct aws_allocator *alloc } AWS_TEST_CASE(credentials_provider_process_new_failed, s_credentials_provider_process_new_failed); -static int s_credentials_provider_process_bad_command(struct aws_allocator *allocator, void *ctx) { - (void)ctx; +static int s_test_command_expect_failure(struct aws_allocator *allocator, const struct aws_string *command) { s_aws_process_tester_init(allocator); struct aws_byte_buf content_buf; struct aws_byte_buf existing_content = aws_byte_buf_from_c_str(aws_string_c_str(s_process_config_file_contents)); aws_byte_buf_init_copy(&content_buf, allocator, &existing_content); - struct aws_byte_cursor cursor = aws_byte_cursor_from_string(s_bad_test_command); + struct aws_byte_cursor cursor = aws_byte_cursor_from_string(command); ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); cursor = aws_byte_cursor_from_c_str("\n"); ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); @@ -304,49 +325,16 @@ static int s_credentials_provider_process_bad_command(struct aws_allocator *allo s_aws_process_tester_cleanup(); return 0; } + +static int s_credentials_provider_process_bad_command(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + return s_test_command_expect_failure(allocator, s_bad_test_command); +} AWS_TEST_CASE(credentials_provider_process_bad_command, s_credentials_provider_process_bad_command); static int s_credentials_provider_process_incorrect_command_output(struct aws_allocator *allocator, void *ctx) { (void)ctx; - - s_aws_process_tester_init(allocator); - - struct aws_byte_buf content_buf; - struct aws_byte_buf existing_content = aws_byte_buf_from_c_str(aws_string_c_str(s_process_config_file_contents)); - aws_byte_buf_init_copy(&content_buf, allocator, &existing_content); - struct aws_byte_cursor cursor = aws_byte_cursor_from_string(s_bad_command_output); - ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); - cursor = aws_byte_cursor_from_c_str("\n"); - ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); - - struct aws_string *config_file_contents = aws_string_new_from_array(allocator, content_buf.buffer, content_buf.len); - ASSERT_TRUE(config_file_contents != NULL); - aws_byte_buf_clean_up(&content_buf); - - s_aws_process_test_init_config_profile(allocator, config_file_contents); - aws_string_destroy(config_file_contents); - - struct aws_credentials_provider_process_options options = { - .shutdown_options = - { - .shutdown_callback = s_on_shutdown_complete, - .shutdown_user_data = NULL, - }, - .profile_to_use = aws_byte_cursor_from_string(s_credentials_process_profile), - }; - struct aws_credentials_provider *provider = aws_credentials_provider_new_process(allocator, &options); - ASSERT_NOT_NULL(provider); - aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL); - - s_aws_wait_for_credentials_result(); - - ASSERT_TRUE(s_tester.has_received_credentials_callback == true); - ASSERT_TRUE(s_tester.credentials == NULL); - - aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); - s_aws_process_tester_cleanup(); - return 0; + return s_test_command_expect_failure(allocator, s_bad_command_output); } AWS_TEST_CASE( credentials_provider_process_incorrect_command_output, @@ -367,15 +355,13 @@ static int s_verify_credentials(struct aws_credentials *credentials) { return AWS_OP_SUCCESS; } -static int s_credentials_provider_process_basic_success(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - +static int s_test_command_expect_success(struct aws_allocator *allocator, const struct aws_string *command) { s_aws_process_tester_init(allocator); struct aws_byte_buf content_buf; struct aws_byte_buf existing_content = aws_byte_buf_from_c_str(aws_string_c_str(s_process_config_file_contents)); aws_byte_buf_init_copy(&content_buf, allocator, &existing_content); - struct aws_byte_cursor cursor = aws_byte_cursor_from_string(s_test_command); + struct aws_byte_cursor cursor = aws_byte_cursor_from_string(command); ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); cursor = aws_byte_cursor_from_c_str("\n"); ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS); @@ -409,8 +395,23 @@ static int s_credentials_provider_process_basic_success(struct aws_allocator *al s_aws_process_tester_cleanup(); return 0; } + +static int s_credentials_provider_process_basic_success(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + return s_test_command_expect_success(allocator, s_test_command); +} AWS_TEST_CASE(credentials_provider_process_basic_success, s_credentials_provider_process_basic_success); +/* Test that stderr is ignored, if the process otherwise succeeds with exit code 0 and valid JSON to stdout. + * Once upon a time stderr and stdout were merged, and mundane logging to stderr would break things. */ +static int s_credentials_provider_process_success_ignores_stderr(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + return s_test_command_expect_success(allocator, s_test_command_with_logging_on_stderr); +} +AWS_TEST_CASE( + credentials_provider_process_success_ignores_stderr, + s_credentials_provider_process_success_ignores_stderr); + static int s_credentials_provider_process_basic_success_from_profile_provider( struct aws_allocator *allocator, void *ctx) { From a30de74b49cab2b34a0d6a5cd47804f31e441e95 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 12 Sep 2024 14:42:18 -0700 Subject: [PATCH 07/10] Fix Multiple Shutdown Callback for Profile with STS Code Path (#251) --- source/credentials_provider_profile.c | 14 +++-- tests/credentials_provider_sts_tests.c | 73 +++++++++++++++++++------- 2 files changed, 63 insertions(+), 24 deletions(-) diff --git a/source/credentials_provider_profile.c b/source/credentials_provider_profile.c index 50a0f0d3..264e42ba 100644 --- a/source/credentials_provider_profile.c +++ b/source/credentials_provider_profile.c @@ -344,11 +344,15 @@ static struct aws_credentials_provider *s_create_sts_based_provider( "static: source_profile set to %s", aws_string_c_str(aws_profile_property_get_value(source_profile_property))); - struct aws_credentials_provider_profile_options profile_provider_options = *options; - profile_provider_options.profile_name_override = - aws_byte_cursor_from_string(aws_profile_property_get_value(source_profile_property)); - /* reuse profile collection instead of reading it again */ - profile_provider_options.profile_collection_cached = merged_profiles; + struct aws_credentials_provider_profile_options profile_provider_options = { + .bootstrap = options->bootstrap, + .profile_name_override = + aws_byte_cursor_from_string(aws_profile_property_get_value(source_profile_property)), + /* reuse profile collection instead of reading it again */ + .profile_collection_cached = merged_profiles, + .tls_ctx = options->tls_ctx, + .function_table = options->function_table, + }; sts_options.creds_provider = s_credentials_provider_new_profile_internal(allocator, &profile_provider_options, source_profiles_table); diff --git a/tests/credentials_provider_sts_tests.c b/tests/credentials_provider_sts_tests.c index cee07e8d..f3896db8 100644 --- a/tests/credentials_provider_sts_tests.c +++ b/tests/credentials_provider_sts_tests.c @@ -57,6 +57,8 @@ struct aws_mock_sts_tester { bool fail_connection; + int provider_shutdown_callback_count; + struct aws_event_loop_group *el_group; struct aws_host_resolver *resolver; @@ -78,16 +80,40 @@ static void s_on_connection_manager_shutdown_complete(void *user_data) { aws_condition_variable_notify_one(&s_tester.signal); } -static bool s_has_tester_received_shutdown_callback(void *user_data) { +static bool s_has_tester_received_connection_manager_shutdown_callback(void *user_data) { (void)user_data; return s_tester.mocked_connection_manager_shutdown_callback_count == s_tester.expected_connection_manager_shutdown_callback_count; } +static void s_aws_wait_for_connection_manager_shutdown_callback(void) { + aws_mutex_lock(&s_tester.lock); + aws_condition_variable_wait_pred( + &s_tester.signal, &s_tester.lock, s_has_tester_received_connection_manager_shutdown_callback, NULL); + aws_mutex_unlock(&s_tester.lock); +} + +static void s_on_provider_shutdown(void *user_data) { + (void)user_data; + + aws_mutex_lock(&s_tester.lock); + s_tester.provider_shutdown_callback_count++; + aws_mutex_unlock(&s_tester.lock); + + aws_condition_variable_notify_one(&s_tester.signal); +} + +static bool s_has_tester_received_provider_shutdown_callback(void *user_data) { + (void)user_data; + + return s_tester.provider_shutdown_callback_count; +} + static void s_aws_wait_for_provider_shutdown_callback(void) { aws_mutex_lock(&s_tester.lock); - aws_condition_variable_wait_pred(&s_tester.signal, &s_tester.lock, s_has_tester_received_shutdown_callback, NULL); + aws_condition_variable_wait_pred( + &s_tester.signal, &s_tester.lock, s_has_tester_received_provider_shutdown_callback, NULL); aws_mutex_unlock(&s_tester.lock); } @@ -508,7 +534,7 @@ static int s_credentials_provider_sts_direct_config_succeeds_fn(struct aws_alloc s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -561,7 +587,7 @@ static int s_credentials_provider_sts_direct_config_with_external_id_succeeds_fn s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -658,7 +684,7 @@ static int s_credentials_provider_sts_direct_config_with_region_succeeds_fn( s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -741,7 +767,7 @@ static int s_credentials_provider_sts_direct_config_with_default_region_succeeds s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -829,7 +855,7 @@ static int s_credentials_provider_sts_direct_config_with_region_from_config_succ s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); aws_file_delete(config_file_str); aws_string_destroy(config_file_str); @@ -915,7 +941,7 @@ static int s_credentials_provider_sts_direct_config_succeeds_after_retry_fn( s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -999,7 +1025,7 @@ static int s_credentials_provider_sts_direct_config_invalid_doc_fn(struct aws_al s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -1046,7 +1072,7 @@ static int s_credentials_provider_sts_direct_config_connection_failed_fn(struct ASSERT_NULL(s_tester.credentials); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -1096,7 +1122,7 @@ static int s_credentials_provider_sts_direct_config_service_fails_fn(struct aws_ ASSERT_NULL(s_tester.credentials); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -1166,6 +1192,10 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_fn(struct a .profile_name_override = aws_byte_cursor_from_c_str("roletest"), .bootstrap = s_tester.bootstrap, .function_table = &s_mock_function_table, + .shutdown_options = + { + .shutdown_callback = s_on_provider_shutdown, + }, }; int expected_num_requests = 3; for (int i = 0; i < expected_num_requests; i++) { @@ -1223,7 +1253,12 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_fn(struct a } aws_credentials_provider_release(provider); + s_aws_wait_for_connection_manager_shutdown_callback(); s_aws_wait_for_provider_shutdown_callback(); + /* There used to be a bug that triggered the shutdown callback multiple times. Sleep for a few seconds + * and validate that we don't trigger the shutdown callback multiple times */ + aws_thread_current_sleep(3000000000); + ASSERT_INT_EQUALS(1, s_tester.provider_shutdown_callback_count); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1331,7 +1366,7 @@ static int s_credentials_provider_sts_from_profile_config_with_ecs_credentials_s } aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_string_destroy(relative_uri_str); aws_string_destroy(config_file_str); aws_string_destroy(creds_file_str); @@ -1443,7 +1478,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_and_profile } aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1514,7 +1549,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_and_partial ASSERT_NULL(s_tester.credentials); ASSERT_INT_EQUALS(s_tester.error_code, AWS_AUTH_SIGNING_NO_CREDENTIALS); aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1607,7 +1642,7 @@ static int s_credentials_provider_sts_from_self_referencing_profile_fn(struct aw } aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1813,7 +1848,7 @@ static int s_credentials_provider_sts_from_profile_config_succeeds( s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1885,7 +1920,7 @@ static int s_credentials_provider_sts_from_profile_config_with_external_id_fn( s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); return AWS_OP_SUCCESS; @@ -1982,7 +2017,7 @@ static int s_credentials_provider_sts_from_profile_config_environment_succeeds_f s_tester.mocked_requests[0].body.len); aws_credentials_provider_release(provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); @@ -2105,7 +2140,7 @@ static int s_credentials_provider_sts_cache_expiration_conflict(struct aws_alloc aws_credentials_provider_release(cached_provider); aws_credentials_provider_release(sts_provider); - s_aws_wait_for_provider_shutdown_callback(); + s_aws_wait_for_connection_manager_shutdown_callback(); aws_credentials_provider_release(static_provider); ASSERT_SUCCESS(s_aws_sts_tester_cleanup()); From c5e7c618cd333367ec56173ead8b78e2672d085c Mon Sep 17 00:00:00 2001 From: Dmitriy Musatkin <63878209+DmitriyMusatkin@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:28:54 -0700 Subject: [PATCH 08/10] Add more partitions for sts cred provider (#253) --- .gitignore | 1 + include/aws/auth/private/credentials_utils.h | 4 +- source/credentials_utils.c | 56 +++++++-- tests/CMakeLists.txt | 2 + tests/credentials_provider_sts_tests.c | 114 +++++++++---------- tests/credentials_utils_tests.c | 58 ++++++++++ 6 files changed, 169 insertions(+), 66 deletions(-) create mode 100644 tests/credentials_utils_tests.c diff --git a/.gitignore b/.gitignore index 6a8a3686..8b120dc3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ Release *# *.iml tags +.vscode #vim swap file *.swp diff --git a/include/aws/auth/private/credentials_utils.h b/include/aws/auth/private/credentials_utils.h index 269789e9..041023b0 100644 --- a/include/aws/auth/private/credentials_utils.h +++ b/include/aws/auth/private/credentials_utils.h @@ -144,7 +144,7 @@ void aws_credentials_provider_invoke_shutdown_callback(struct aws_credentials_pr * A valid credentials must have "access key" and "secrete access key". * For some services, token and expiration are not required. * So in this API, the keys are provided by callers and this API will - * performe a case insensitive search. + * perform a case insensitive search. */ AWS_AUTH_API struct aws_credentials *aws_parse_credentials_from_aws_json_object( @@ -154,7 +154,7 @@ struct aws_credentials *aws_parse_credentials_from_aws_json_object( /** * This API is similar to aws_parse_credentials_from_aws_json_object, - * except it accpets a char buffer json document as it's input. + * except it accepts a char buffer json document as it's input. */ AWS_AUTH_API struct aws_credentials *aws_parse_credentials_from_json_document( diff --git a/source/credentials_utils.c b/source/credentials_utils.c index b032f541..2cc48a29 100644 --- a/source/credentials_utils.c +++ b/source/credentials_utils.c @@ -359,8 +359,29 @@ struct aws_profile_collection *aws_load_profile_collection_from_config_file( } static struct aws_byte_cursor s_dot_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("."); -static struct aws_byte_cursor s_amazonaws_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazonaws.com"); -static struct aws_byte_cursor s_cn_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(".cn"); + +/* AWS */ +static struct aws_byte_cursor s_aws_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazonaws.com"); + +/* AWS CN */ +static struct aws_byte_cursor s_cn_region_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("cn-"); +static struct aws_byte_cursor s_aws_cn_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("amazonaws.com.cn"); + +/* AWS ISO */ +static struct aws_byte_cursor s_iso_region_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("us-iso-"); +static struct aws_byte_cursor s_aws_iso_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("c2s.ic.gov"); + +/* AWS ISO B */ +static struct aws_byte_cursor s_isob_region_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("us-isob-"); +static struct aws_byte_cursor s_aws_isob_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("sc2s.sgov.gov"); + +/* AWS ISO E */ +static struct aws_byte_cursor s_isoe_region_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("eu-isoe-"); +static struct aws_byte_cursor s_aws_isoe_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("cloud.adc-e.uk"); + +/* AWS ISO F */ +static struct aws_byte_cursor s_isof_region_prefix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("us-isof-"); +static struct aws_byte_cursor s_aws_isof_dns_suffix = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("csp.hci.ic.gov"); int aws_credentials_provider_construct_regional_endpoint( struct aws_allocator *allocator, @@ -384,17 +405,38 @@ int aws_credentials_provider_construct_regional_endpoint( if (aws_byte_buf_append_dynamic(&endpoint, &service_cursor) || aws_byte_buf_append_dynamic(&endpoint, &s_dot_cursor) || aws_byte_buf_append_dynamic(&endpoint, ®ion_cursor) || - aws_byte_buf_append_dynamic(&endpoint, &s_dot_cursor) || - aws_byte_buf_append_dynamic(&endpoint, &s_amazonaws_cursor)) { + aws_byte_buf_append_dynamic(&endpoint, &s_dot_cursor)) { goto on_error; } - if (aws_string_eq_c_str_ignore_case(region, "cn-north-1") || - aws_string_eq_c_str_ignore_case(region, "cn-northwest-1")) { - if (aws_byte_buf_append_dynamic(&endpoint, &s_cn_cursor)) { + const struct aws_byte_cursor region_cur = aws_byte_cursor_from_string(region); + + if (aws_byte_cursor_starts_with(®ion_cur, &s_cn_region_prefix)) { /* AWS CN partition */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_cn_dns_suffix)) { + goto on_error; + } + } else if (aws_byte_cursor_starts_with(®ion_cur, &s_iso_region_prefix)) { /* AWS ISO partition */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_iso_dns_suffix)) { + goto on_error; + } + } else if (aws_byte_cursor_starts_with(®ion_cur, &s_isob_region_prefix)) { /* AWS ISOB partition */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_isob_dns_suffix)) { + goto on_error; + } + } else if (aws_byte_cursor_starts_with(®ion_cur, &s_isoe_region_prefix)) { /* AWS ISOE partition */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_isoe_dns_suffix)) { + goto on_error; + } + } else if (aws_byte_cursor_starts_with(®ion_cur, &s_isof_region_prefix)) { /* AWS ISOF partition */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_isof_dns_suffix)) { + goto on_error; + } + } else { /* Assume AWS partition for all other regions */ + if (aws_byte_buf_append_dynamic(&endpoint, &s_aws_dns_suffix)) { goto on_error; } } + *out_endpoint = aws_string_new_from_buf(allocator, &endpoint); result = AWS_OP_SUCCESS; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a2f9bf6a..b884191d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -190,6 +190,8 @@ add_test_case(credentials_file_path_environment_test) add_test_case(profile_override_test) add_test_case(profile_environment_test) +add_test_case(credentials_utils_construct_endpoint_test) + add_test_case(sigv4_skip_xray_header_test) add_test_case(sigv4_skip_user_agent_header_test) add_test_case(sigv4_skip_custom_header_test) diff --git a/tests/credentials_provider_sts_tests.c b/tests/credentials_provider_sts_tests.c index f3896db8..3ab73258 100644 --- a/tests/credentials_provider_sts_tests.c +++ b/tests/credentials_provider_sts_tests.c @@ -1268,10 +1268,10 @@ AWS_TEST_CASE( s_credentials_provider_sts_from_profile_config_with_chain_fn) AWS_STATIC_STRING_FROM_LITERAL(s_ecs_creds_env_relative_uri, "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"); -static const char *s_soure_credentials_ecs_config_file = "[default]\n" - "role_arn=arn:aws:iam::67895:role/test_role\n" - "credential_source=EcsContainer\n" - "role_session_name=test_session\n"; +static const char *s_source_credentials_ecs_config_file = "[default]\n" + "role_arn=arn:aws:iam::67895:role/test_role\n" + "credential_source=EcsContainer\n" + "role_session_name=test_session\n"; static struct aws_byte_cursor s_ecs_good_response = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL( "{\"AccessKeyId\":\"SuccessfulAccessKey\", \n \"SecretAccessKey\":\"SuccessfulSecret\", \n " "\"Token\":\"TokenSuccess\", \n \"Expiration\":\"2020-02-25T06:03:31Z\"}"); @@ -1290,9 +1290,9 @@ static int s_credentials_provider_sts_from_profile_config_with_ecs_credentials_s ASSERT_SUCCESS(aws_set_environment_value(s_ecs_creds_env_relative_uri, relative_uri_str)); s_aws_sts_tester_init(allocator); - /* one for ecs provdier and one for sts provider */ + /* one for ecs provider and one for sts provider */ s_tester.expected_connection_manager_shutdown_callback_count = 2; - struct aws_string *config_contents = aws_string_new_from_c_str(allocator, s_soure_credentials_ecs_config_file); + struct aws_string *config_contents = aws_string_new_from_c_str(allocator, s_source_credentials_ecs_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); @@ -1378,24 +1378,24 @@ AWS_TEST_CASE( credentials_provider_sts_from_profile_config_with_ecs_credentials_source, s_credentials_provider_sts_from_profile_config_with_ecs_credentials_source_fn) -static const char *s_soure_profile_chain_and_profile_config_file = "[default]\n" - "aws_access_key_id=BLAHBLAH\n" - "aws_secret_access_key=BLAHBLAHBLAH\n" - "\n" - "[roletest]\n" - "role_arn=arn:aws:iam::67895:role/test_role\n" - "source_profile=roletest2\n" - "role_session_name=test_session\n" - "[roletest2]\n" - "role_arn=arn:aws:iam::67896:role/test_role\n" - "source_profile=roletest3\n" - "role_session_name=test_session2\n" - "[roletest3]\n" - "role_arn=arn:aws:iam::67897:role/test_role\n" - "source_profile=default\n" - "role_session_name=test_session3\n" - "aws_access_key_id = BLAH\n" - "aws_secret_access_key = BLAHBLAH\n"; +static const char *s_source_profile_chain_and_profile_config_file = "[default]\n" + "aws_access_key_id=BLAHBLAH\n" + "aws_secret_access_key=BLAHBLAHBLAH\n" + "\n" + "[roletest]\n" + "role_arn=arn:aws:iam::67895:role/test_role\n" + "source_profile=roletest2\n" + "role_session_name=test_session\n" + "[roletest2]\n" + "role_arn=arn:aws:iam::67896:role/test_role\n" + "source_profile=roletest3\n" + "role_session_name=test_session2\n" + "[roletest3]\n" + "role_arn=arn:aws:iam::67897:role/test_role\n" + "source_profile=default\n" + "role_session_name=test_session3\n" + "aws_access_key_id = BLAH\n" + "aws_secret_access_key = BLAHBLAH\n"; static int s_credentials_provider_sts_from_profile_config_with_chain_and_profile_creds_fn( struct aws_allocator *allocator, void *ctx) { @@ -1408,7 +1408,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_and_profile s_aws_sts_tester_init(allocator); s_tester.expected_connection_manager_shutdown_callback_count = 2; struct aws_string *config_contents = - aws_string_new_from_c_str(allocator, s_soure_profile_chain_and_profile_config_file); + aws_string_new_from_c_str(allocator, s_source_profile_chain_and_profile_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); @@ -1487,7 +1487,7 @@ AWS_TEST_CASE( credentials_provider_sts_from_profile_config_with_chain_and_profile_creds, s_credentials_provider_sts_from_profile_config_with_chain_and_profile_creds_fn) -static const char *s_soure_profile_chain_and_partial_profile_config_file = +static const char *s_source_profile_chain_and_partial_profile_config_file = "[default]\n" "aws_access_key_id=BLAHBLAH\n" "aws_secret_access_key=BLAHBLAHBLAH\n" @@ -1517,7 +1517,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_and_partial s_aws_sts_tester_init(allocator); s_tester.expected_connection_manager_shutdown_callback_count = 2; struct aws_string *config_contents = - aws_string_new_from_c_str(allocator, s_soure_profile_chain_and_partial_profile_config_file); + aws_string_new_from_c_str(allocator, s_source_profile_chain_and_partial_profile_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); @@ -1558,16 +1558,16 @@ AWS_TEST_CASE( credentials_provider_sts_from_profile_config_with_chain_and_partial_profile_creds, s_credentials_provider_sts_from_profile_config_with_chain_and_partial_profile_creds_fn) -static const char *s_soure_profile_self_assume_role_config_file = "[default]\n" - "aws_access_key_id=BLAHBLAH\n" - "aws_secret_access_key=BLAHBLAHBLAH\n" - "\n" - "[roletest]\n" - "role_arn=arn:aws:iam::67895:role/test_role\n" - "source_profile=roletest\n" - "role_session_name=test_session\n" - "aws_access_key_id = BLAH\n" - "aws_secret_access_key = BLAHBLAH\n"; +static const char *s_source_profile_self_assume_role_config_file = "[default]\n" + "aws_access_key_id=BLAHBLAH\n" + "aws_secret_access_key=BLAHBLAHBLAH\n" + "\n" + "[roletest]\n" + "role_arn=arn:aws:iam::67895:role/test_role\n" + "source_profile=roletest\n" + "role_session_name=test_session\n" + "aws_access_key_id = BLAH\n" + "aws_secret_access_key = BLAHBLAH\n"; static int s_credentials_provider_sts_from_self_referencing_profile_fn(struct aws_allocator *allocator, void *ctx) { (void)ctx; @@ -1577,7 +1577,7 @@ static int s_credentials_provider_sts_from_self_referencing_profile_fn(struct aw s_aws_sts_tester_init(allocator); struct aws_string *config_contents = - aws_string_new_from_c_str(allocator, s_soure_profile_self_assume_role_config_file); + aws_string_new_from_c_str(allocator, s_source_profile_self_assume_role_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); @@ -1651,22 +1651,22 @@ AWS_TEST_CASE( credentials_provider_sts_from_self_referencing_profile, s_credentials_provider_sts_from_self_referencing_profile_fn) -static const char *s_soure_profile_chain_cycle_config_file = "[default]\n" - "aws_access_key_id=BLAHBLAH\n" - "aws_secret_access_key=BLAHBLAHBLAH\n" - "\n" - "[roletest]\n" - "role_arn=arn:aws:iam::67895:role/test_role\n" - "source_profile=roletest2\n" - "role_session_name=test_session\n" - "[roletest2]\n" - "role_arn=arn:aws:iam::67896:role/test_role\n" - "source_profile=roletest3\n" - "role_session_name=test_session2\n" - "[roletest3]\n" - "role_arn=arn:aws:iam::67897:role/test_role\n" - "source_profile=roletest2\n" - "role_session_name=test_session3\n"; +static const char *s_source_profile_chain_cycle_config_file = "[default]\n" + "aws_access_key_id=BLAHBLAH\n" + "aws_secret_access_key=BLAHBLAHBLAH\n" + "\n" + "[roletest]\n" + "role_arn=arn:aws:iam::67895:role/test_role\n" + "source_profile=roletest2\n" + "role_session_name=test_session\n" + "[roletest2]\n" + "role_arn=arn:aws:iam::67896:role/test_role\n" + "source_profile=roletest3\n" + "role_session_name=test_session2\n" + "[roletest3]\n" + "role_arn=arn:aws:iam::67897:role/test_role\n" + "source_profile=roletest2\n" + "role_session_name=test_session3\n"; static int s_credentials_provider_sts_from_profile_config_with_chain_cycle_fn( struct aws_allocator *allocator, @@ -1679,7 +1679,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_cycle_fn( s_aws_sts_tester_init(allocator); - struct aws_string *config_contents = aws_string_new_from_c_str(allocator, s_soure_profile_chain_cycle_config_file); + struct aws_string *config_contents = aws_string_new_from_c_str(allocator, s_source_profile_chain_cycle_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); @@ -1712,7 +1712,7 @@ AWS_TEST_CASE( credentials_provider_sts_from_profile_config_with_chain_cycle, s_credentials_provider_sts_from_profile_config_with_chain_cycle_fn) -static const char *s_soure_profile_chain_cycle_and_static_creds_config_file = +static const char *s_source_profile_chain_cycle_and_static_creds_config_file = "[roletest]\n" "role_arn=arn:aws:iam::67895:role/test_role\n" "source_profile=roletest2\n" @@ -1740,7 +1740,7 @@ static int s_credentials_provider_sts_from_profile_config_with_chain_cycle_and_p s_aws_sts_tester_init(allocator); struct aws_string *config_contents = - aws_string_new_from_c_str(allocator, s_soure_profile_chain_cycle_and_static_creds_config_file); + aws_string_new_from_c_str(allocator, s_source_profile_chain_cycle_and_static_creds_config_file); struct aws_string *config_file_str = aws_create_process_unique_file_name(allocator); struct aws_string *creds_file_str = aws_create_process_unique_file_name(allocator); diff --git a/tests/credentials_utils_tests.c b/tests/credentials_utils_tests.c new file mode 100644 index 00000000..2ef5c79e --- /dev/null +++ b/tests/credentials_utils_tests.c @@ -0,0 +1,58 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include +#include + +static int s_credentials_utils_construct_endpoint_test(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + struct aws_string *service_name = aws_string_new_from_c_str(allocator, "sts"); + + struct aws_string *endpoint; + struct aws_string *region; + + region = aws_string_new_from_c_str(allocator, "us-east-2"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.us-east-2.amazonaws.com", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + region = aws_string_new_from_c_str(allocator, "cn-northwest-1"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.cn-northwest-1.amazonaws.com.cn", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + region = aws_string_new_from_c_str(allocator, "us-iso-east-1"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.us-iso-east-1.c2s.ic.gov", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + region = aws_string_new_from_c_str(allocator, "us-isob-east-1"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.us-isob-east-1.sc2s.sgov.gov", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + region = aws_string_new_from_c_str(allocator, "eu-isoe-west-1"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.eu-isoe-west-1.cloud.adc-e.uk", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + region = aws_string_new_from_c_str(allocator, "us-isof-south-1"); + ASSERT_SUCCESS(aws_credentials_provider_construct_regional_endpoint(allocator, &endpoint, region, service_name)); + ASSERT_STR_EQUALS("sts.us-isof-south-1.csp.hci.ic.gov", aws_string_c_str(endpoint)); + aws_string_destroy(endpoint); + aws_string_destroy(region); + + aws_string_destroy(service_name); + + return 0; +} + +AWS_TEST_CASE(credentials_utils_construct_endpoint_test, s_credentials_utils_construct_endpoint_test); From 3500e710d5178252c1826b1d574634ec38becfde Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 18 Oct 2024 10:37:51 -0700 Subject: [PATCH 09/10] Update cmake_minimum_required to 3.9 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ae7271e..99e6a76c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.13) +cmake_minimum_required(VERSION 3.9) project(aws-c-auth C) if (DEFINED CMAKE_PREFIX_PATH) From 7b4ba76b502955ea29a60032c906b9e0e8ba8365 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 18 Oct 2024 11:01:10 -0700 Subject: [PATCH 10/10] Update CMake version requirements to 3.9 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0241796..f465b624 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This library is licensed under the Apache 2.0 License. ### Building -CMake 3.13+ is required to build. +CMake 3.9+ is required to build. `` must be an absolute path in the following instructions.