123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /**
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0.
- */
- #include <aws/auth/credentials.h>
- #include <aws/auth/private/aws_profile.h>
- #include <aws/auth/private/credentials_utils.h>
- #include <aws/common/clock.h>
- #include <aws/common/date_time.h>
- #include <aws/common/environment.h>
- #include <aws/common/process.h>
- #include <aws/common/string.h>
- #if defined(_MSC_VER)
- # pragma warning(disable : 4204)
- #endif /* _MSC_VER */
- struct aws_credentials_provider_process_impl {
- struct aws_string *command;
- };
- static int s_get_credentials_from_process(
- struct aws_credentials_provider *provider,
- aws_on_get_credentials_callback_fn callback,
- void *user_data) {
- struct aws_credentials_provider_process_impl *impl = provider->impl;
- struct aws_credentials *credentials = NULL;
- struct aws_run_command_options options = {
- .command = aws_string_c_str(impl->command),
- };
- struct aws_run_command_result result;
- int ret = AWS_OP_ERR;
- if (aws_run_command_result_init(provider->allocator, &result)) {
- goto on_finish;
- }
- if (aws_run_command(provider->allocator, &options, &result) || result.ret_code || !result.std_out) {
- AWS_LOGF_ERROR(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "(id=%p) Failed to source credentials from running process credentials provider with command: %s, err:%s",
- (void *)provider,
- aws_string_c_str(impl->command),
- aws_error_str(aws_last_error()));
- goto on_finish;
- }
- struct aws_parse_credentials_from_json_doc_options parse_options = {
- .access_key_id_name = "AccessKeyId",
- .secret_access_key_name = "SecretAccessKey",
- .token_name = "Token",
- .expiration_name = "Expiration",
- .token_required = false,
- .expiration_required = false,
- };
- credentials = aws_parse_credentials_from_json_document(
- provider->allocator, aws_byte_cursor_from_string(result.std_out), &parse_options);
- if (!credentials) {
- AWS_LOGF_INFO(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "(id=%p) Process credentials provider failed to parse credentials from command output (output is not "
- "logged in case sensitive information).",
- (void *)provider);
- goto on_finish;
- }
- AWS_LOGF_INFO(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "(id=%p) Process credentials provider successfully sourced credentials.",
- (void *)provider);
- ret = AWS_OP_SUCCESS;
- on_finish:
- ;
- int error_code = AWS_ERROR_SUCCESS;
- if (credentials == NULL) {
- error_code = aws_last_error();
- if (error_code == AWS_ERROR_SUCCESS) {
- error_code = AWS_AUTH_CREDENTIALS_PROVIDER_PROCESS_SOURCE_FAILURE;
- }
- }
- callback(credentials, error_code, user_data);
- aws_run_command_result_cleanup(&result);
- aws_credentials_release(credentials);
- return ret;
- }
- static void s_credentials_provider_process_destroy(struct aws_credentials_provider *provider) {
- struct aws_credentials_provider_process_impl *impl = provider->impl;
- if (impl) {
- aws_string_destroy_secure(impl->command);
- }
- aws_credentials_provider_invoke_shutdown_callback(provider);
- aws_mem_release(provider->allocator, provider);
- }
- AWS_STATIC_STRING_FROM_LITERAL(s_credentials_process, "credential_process");
- static struct aws_byte_cursor s_default_profile_name_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("default");
- static struct aws_profile_collection *s_load_profile(struct aws_allocator *allocator) {
- struct aws_profile_collection *config_profiles = NULL;
- struct aws_string *config_file_path = NULL;
- config_file_path = aws_get_config_file_path(allocator, NULL);
- if (!config_file_path) {
- AWS_LOGF_ERROR(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Failed to resolve config file path during process credentials provider initialization: %s",
- aws_error_str(aws_last_error()));
- goto on_done;
- }
- config_profiles = aws_profile_collection_new_from_file(allocator, config_file_path, AWS_PST_CONFIG);
- if (config_profiles != NULL) {
- AWS_LOGF_DEBUG(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Successfully built config profile collection from file at (%s)",
- aws_string_c_str(config_file_path));
- } else {
- AWS_LOGF_ERROR(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Failed to build config profile collection from file at (%s) : %s",
- aws_string_c_str(config_file_path),
- aws_error_str(aws_last_error()));
- goto on_done;
- }
- on_done:
- aws_string_destroy(config_file_path);
- return config_profiles;
- }
- static void s_check_or_get_with_profile_config(
- struct aws_allocator *allocator,
- const struct aws_profile *profile,
- const struct aws_string *config_key,
- struct aws_byte_buf *target) {
- if (!allocator || !profile || !config_key || !target) {
- return;
- }
- if (!target->len) {
- aws_byte_buf_clean_up(target);
- const struct aws_profile_property *property = aws_profile_get_property(profile, config_key);
- if (property) {
- aws_byte_buf_init_copy_from_cursor(
- target, allocator, aws_byte_cursor_from_string(aws_profile_property_get_value(property)));
- }
- }
- }
- static struct aws_byte_cursor s_stderr_redirect_to_stdout = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(" 2>&1");
- static struct aws_string *s_get_command(struct aws_allocator *allocator, struct aws_byte_cursor profile_cursor) {
- struct aws_byte_buf command_buf;
- AWS_ZERO_STRUCT(command_buf);
- struct aws_string *command = NULL;
- struct aws_profile_collection *config_profiles = NULL;
- struct aws_string *profile_name = NULL;
- const struct aws_profile *profile = NULL;
- config_profiles = s_load_profile(allocator);
- if (profile_cursor.len == 0) {
- profile_name = aws_get_profile_name(allocator, &s_default_profile_name_cursor);
- } else {
- profile_name = aws_string_new_from_array(allocator, profile_cursor.ptr, profile_cursor.len);
- }
- if (config_profiles && profile_name) {
- profile = aws_profile_collection_get_profile(config_profiles, profile_name);
- }
- if (!profile) {
- AWS_LOGF_ERROR(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Failed to resolve config profile during process credentials provider initialization.");
- goto on_finish;
- }
- s_check_or_get_with_profile_config(allocator, profile, s_credentials_process, &command_buf);
- if (!command_buf.len) {
- AWS_LOGF_ERROR(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Failed to resolve credentials_process command during process credentials provider initialization.");
- goto on_finish;
- }
- if (aws_byte_buf_append_dynamic(&command_buf, &s_stderr_redirect_to_stdout)) {
- goto on_finish;
- }
- command = aws_string_new_from_array(allocator, command_buf.buffer, command_buf.len);
- if (!command) {
- goto on_finish;
- }
- AWS_LOGF_DEBUG(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "Successfully loaded credentials_process command for process credentials provider.");
- on_finish:
- aws_string_destroy(profile_name);
- aws_profile_collection_destroy(config_profiles);
- aws_byte_buf_clean_up_secure(&command_buf);
- return command;
- }
- static struct aws_credentials_provider_vtable s_aws_credentials_provider_process_vtable = {
- .get_credentials = s_get_credentials_from_process,
- .destroy = s_credentials_provider_process_destroy,
- };
- struct aws_credentials_provider *aws_credentials_provider_new_process(
- struct aws_allocator *allocator,
- const struct aws_credentials_provider_process_options *options) {
- struct aws_credentials_provider *provider = NULL;
- struct aws_credentials_provider_process_impl *impl = NULL;
- aws_mem_acquire_many(
- allocator,
- 2,
- &provider,
- sizeof(struct aws_credentials_provider),
- &impl,
- sizeof(struct aws_credentials_provider_process_impl));
- if (!provider) {
- goto on_error;
- }
- AWS_ZERO_STRUCT(*provider);
- AWS_ZERO_STRUCT(*impl);
- impl->command = s_get_command(allocator, options->profile_to_use);
- if (!impl->command) {
- goto on_error;
- }
- aws_credentials_provider_init_base(provider, allocator, &s_aws_credentials_provider_process_vtable, impl);
- provider->shutdown_options = options->shutdown_options;
- AWS_LOGF_TRACE(
- AWS_LS_AUTH_CREDENTIALS_PROVIDER,
- "(id=%p): Successfully initializing a process credentials provider.",
- (void *)provider);
- return provider;
- on_error:
- aws_mem_release(allocator, provider);
- return NULL;
- }
|