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);