Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assumeRole chain support #224

Merged
merged 30 commits into from
Jan 18, 2024
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
67c213b
Initial assumeRole chain
waahm7 Jan 10, 2024
2eae450
temp recursion detection support
waahm7 Jan 10, 2024
d93a72b
WIP use static cred if available instead of going through the chain
waahm7 Jan 10, 2024
08de613
refactor
waahm7 Jan 10, 2024
17a41d0
fix declaration
waahm7 Jan 10, 2024
877f0b1
Add cycle detection test
waahm7 Jan 10, 2024
c1912cc
Add tests for more cases
waahm7 Jan 11, 2024
4df49d2
cleanup includes
waahm7 Jan 11, 2024
6922cf9
Fix chain with static creds case
waahm7 Jan 11, 2024
71b94f7
remove const and rename
waahm7 Jan 11, 2024
69715ca
Update comment
waahm7 Jan 11, 2024
b04d960
rename error code
waahm7 Jan 11, 2024
f66992b
update comment
waahm7 Jan 11, 2024
4136812
Use profile provider even if one of the creds are available
waahm7 Jan 11, 2024
9cb8a8f
Cleanup contains creds logic
waahm7 Jan 12, 2024
f5acf59
fix typo
waahm7 Jan 12, 2024
1093132
update comment
waahm7 Jan 12, 2024
b9dcd63
Re-add raise error
waahm7 Jan 12, 2024
84d4891
Update tests
waahm7 Jan 16, 2024
91a53ed
provider error logs
waahm7 Jan 16, 2024
a98b6c5
update profile
waahm7 Jan 16, 2024
dcf1ec0
Reset the test
waahm7 Jan 16, 2024
e1a91ac
add comment and fix ignore case matching
waahm7 Jan 17, 2024
9437736
Use c string instead of byte cursor
waahm7 Jan 17, 2024
cb467b5
fix typos
waahm7 Jan 17, 2024
3eee62c
fix comment
waahm7 Jan 18, 2024
3443882
Update source/credentials_provider_profile.c
waahm7 Jan 18, 2024
e344ad8
lint fix
waahm7 Jan 18, 2024
21c3f20
undo unintentional changes
waahm7 Jan 18, 2024
e178b9b
undo
waahm7 Jan 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add tests for more cases
  • Loading branch information
waahm7 committed Jan 11, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit c1912cca775c54a625d43d4456e283810c641d6e
26 changes: 14 additions & 12 deletions source/credentials_provider_profile.c
Original file line number Diff line number Diff line change
@@ -407,18 +407,6 @@ static struct aws_credentials_provider *s_credentials_provider_new_profile_inter
goto on_finished;
}
struct aws_byte_cursor profile_name_cursor = aws_byte_cursor_from_string(profile_name);
struct aws_hash_element *element = NULL;
if (aws_hash_table_find(source_profile_table, (void *)&profile_name_cursor, &element) == AWS_OP_ERR) {
AWS_LOGF_ERROR(AWS_LS_AUTH_CREDENTIALS_PROVIDER, "hash_table_find failed");
goto on_finished;
}
if (element != NULL) {
// recursion
aws_raise_error(AWS_AUTH_PROFILE_CREDENTIALS_PROVIDER_CYCLE_FAILURE);
goto on_finished;
}

aws_hash_table_put(source_profile_table, (void *)&profile_name_cursor, NULL, 0);

if (options->profile_collection_cached) {
/* Use cached profile collection */
@@ -472,6 +460,20 @@ static struct aws_credentials_provider *s_credentials_provider_new_profile_inter
profile_contains_static_cred = credentials != NULL;
aws_credentials_release(credentials);
}

struct aws_hash_element *element = NULL;
if (aws_hash_table_find(source_profile_table, (void *)&profile_name_cursor, &element) == AWS_OP_ERR) {
AWS_LOGF_ERROR(AWS_LS_AUTH_CREDENTIALS_PROVIDER, "hash_table_find failed");
goto on_finished;
}
if (element != NULL && !profile_contains_static_cred) {
// recursion
aws_raise_error(AWS_AUTH_PROFILE_CREDENTIALS_PROVIDER_CYCLE_FAILURE);
goto on_finished;
}

aws_hash_table_put(source_profile_table, (void *)&profile_name_cursor, NULL, 0);

if (role_arn_property && !profile_contains_static_cred) {
provider = s_create_sts_based_provider(
allocator, role_arn_property, profile, options, merged_profiles, source_profile_table);
2 changes: 2 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -88,6 +88,8 @@ add_net_test_case(credentials_provider_sts_direct_config_connection_failed)
add_net_test_case(credentials_provider_sts_direct_config_service_fails)
add_net_test_case(credentials_provider_sts_from_profile_config_succeeds)
add_net_test_case(credentials_provider_sts_from_profile_config_with_chain)
add_net_test_case(credentials_provider_sts_from_profile_config_with_chain_and_profile_creds)
add_net_test_case(credentials_provider_sts_from_self_referencing_profile)
add_net_test_case(credentials_provider_sts_from_profile_config_with_chain_cycle)
add_net_test_case(credentials_provider_sts_from_profile_config_manual_tls_succeeds)
add_net_test_case(credentials_provider_sts_from_profile_config_environment_succeeds)
200 changes: 200 additions & 0 deletions tests/credentials_provider_sts_tests.c
Original file line number Diff line number Diff line change
@@ -807,6 +807,206 @@ AWS_TEST_CASE(
credentials_provider_sts_from_profile_config_with_chain,
s_credentials_provider_sts_from_profile_config_with_chain_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 int s_credentials_provider_sts_from_profile_config_with_chain_and_profile_creds_fn(
struct aws_allocator *allocator,
void *ctx) {
(void)ctx;

aws_unset_environment_value(s_default_profile_env_variable_name);
aws_unset_environment_value(s_default_config_path_env_variable_name);
aws_unset_environment_value(s_default_credentials_path_env_variable_name);

s_aws_sts_tester_init(allocator);

struct aws_string *config_contents =
aws_string_new_from_c_str(allocator, s_soure_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);

ASSERT_SUCCESS(aws_create_profile_file(creds_file_str, config_contents));
aws_string_destroy(config_contents);

struct aws_credentials_provider_profile_options options = {
.config_file_name_override = aws_byte_cursor_from_string(config_file_str),
.credentials_file_name_override = aws_byte_cursor_from_string(creds_file_str),
.profile_name_override = aws_byte_cursor_from_c_str("roletest"),
.bootstrap = s_tester.bootstrap,
.function_table = &s_mock_function_table,
};

s_tester.mock_body = aws_byte_buf_from_c_str(success_creds_doc);
s_tester.mock_response_code = 200;

struct aws_credentials_provider *provider = aws_credentials_provider_new_profile(allocator, &options);
ASSERT_NOT_NULL(provider);

aws_string_destroy(config_file_str);
aws_string_destroy(creds_file_str);

aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);

s_aws_wait_for_credentials_result();

ASSERT_SUCCESS(s_verify_credentials(s_tester.credentials));

ASSERT_INT_EQUALS(2, s_tester.num_request);
static struct aws_byte_cursor s_expected_request_body[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Version=2011-06-15&Action=AssumeRole&RoleArn=arn%3Aaws%3Aiam%3A%3A67896%"
"3Arole%2Ftest_role&RoleSessionName=test_session2&DurationSeconds=900"),
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Version=2011-06-15&Action=AssumeRole&RoleArn=arn%3Aaws%3Aiam%3A%3A67895%"
"3Arole%2Ftest_role&RoleSessionName=test_session&DurationSeconds=900"),
};
const char *expected_method = "POST";
const char *expected_path = "/";
const char *expected_host_header = "sts.amazonaws.com";

for (int i = 0; i < s_tester.num_request; i++) {
ASSERT_BIN_ARRAYS_EQUALS(
expected_method,
strlen(expected_method),
s_tester.mocked_requests[i].method.buffer,
s_tester.mocked_requests[i].method.len);
ASSERT_BIN_ARRAYS_EQUALS(
expected_path,
strlen(expected_path),
s_tester.mocked_requests[i].path.buffer,
s_tester.mocked_requests[i].path.len);
ASSERT_TRUE(s_tester.mocked_requests[i].had_auth_header);
ASSERT_BIN_ARRAYS_EQUALS(
expected_host_header,
strlen(expected_host_header),
s_tester.mocked_requests[i].host_header.buffer,
s_tester.mocked_requests[i].host_header.len);
ASSERT_BIN_ARRAYS_EQUALS(
s_expected_request_body[i].ptr,
s_expected_request_body[i].len,
s_tester.mocked_requests[i].body.buffer,
s_tester.mocked_requests[i].body.len);
}

aws_credentials_provider_release(provider);

ASSERT_SUCCESS(s_aws_sts_tester_cleanup());

return AWS_OP_SUCCESS;
}
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_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;

aws_unset_environment_value(s_default_profile_env_variable_name);
aws_unset_environment_value(s_default_config_path_env_variable_name);
aws_unset_environment_value(s_default_credentials_path_env_variable_name);

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

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

ASSERT_SUCCESS(aws_create_profile_file(creds_file_str, config_contents));
aws_string_destroy(config_contents);

struct aws_credentials_provider_profile_options options = {
.config_file_name_override = aws_byte_cursor_from_string(config_file_str),
.credentials_file_name_override = aws_byte_cursor_from_string(creds_file_str),
.profile_name_override = aws_byte_cursor_from_c_str("roletest"),
.bootstrap = s_tester.bootstrap,
.function_table = &s_mock_function_table,
};

s_tester.mock_body = aws_byte_buf_from_c_str(success_creds_doc);
s_tester.mock_response_code = 200;

struct aws_credentials_provider *provider = aws_credentials_provider_new_profile(allocator, &options);
ASSERT_NOT_NULL(provider);

aws_string_destroy(config_file_str);
aws_string_destroy(creds_file_str);

aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);

s_aws_wait_for_credentials_result();

ASSERT_SUCCESS(s_verify_credentials(s_tester.credentials));

ASSERT_INT_EQUALS(1, s_tester.num_request);
static struct aws_byte_cursor s_expected_request_body[] = {
AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Version=2011-06-15&Action=AssumeRole&RoleArn=arn%3Aaws%3Aiam%3A%3A67895%"
"3Arole%2Ftest_role&RoleSessionName=test_session&DurationSeconds=900"),
};
const char *expected_method = "POST";
const char *expected_path = "/";
const char *expected_host_header = "sts.amazonaws.com";

for (int i = 0; i < s_tester.num_request; i++) {
ASSERT_BIN_ARRAYS_EQUALS(
expected_method,
strlen(expected_method),
s_tester.mocked_requests[i].method.buffer,
s_tester.mocked_requests[i].method.len);
ASSERT_BIN_ARRAYS_EQUALS(
expected_path,
strlen(expected_path),
s_tester.mocked_requests[i].path.buffer,
s_tester.mocked_requests[i].path.len);
ASSERT_TRUE(s_tester.mocked_requests[i].had_auth_header);
ASSERT_BIN_ARRAYS_EQUALS(
expected_host_header,
strlen(expected_host_header),
s_tester.mocked_requests[i].host_header.buffer,
s_tester.mocked_requests[i].host_header.len);
ASSERT_BIN_ARRAYS_EQUALS(
s_expected_request_body[i].ptr,
s_expected_request_body[i].len,
s_tester.mocked_requests[i].body.buffer,
s_tester.mocked_requests[i].body.len);
}

aws_credentials_provider_release(provider);

ASSERT_SUCCESS(s_aws_sts_tester_cleanup());

return AWS_OP_SUCCESS;
}
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"
Loading