-
-
Notifications
You must be signed in to change notification settings - Fork 275
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
Add function H5FD__s3comms_load_aws_creds_from_env() #5167
base: develop
Are you sure you want to change the base?
Changes from all commits
87b9237
5cb2c56
d438442
b104e7b
8ebf49d
d581624
765b3c6
196ab1d
5652aa0
db22586
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -834,7 +834,7 @@ H5FD_s3comms_s3r_open(const char *url, const char *region, const char *id, const | |
*************************************/ | ||
|
||
if ((region != NULL && *region != '\0') || (id != NULL && *id != '\0') || (signing_key != NULL) || | ||
(token != NULL)) { | ||
(token != NULL && *token != '\0')) { | ||
|
||
size_t tmplen; | ||
|
||
|
@@ -1556,21 +1556,23 @@ H5FD_s3comms_free_purl(parsed_url_t *purl) | |
*/ | ||
static herr_t | ||
H5FD__s3comms_load_aws_creds_from_file(FILE *file, const char *profile_name, char *key_id, char *access_key, | ||
char *aws_region) | ||
char *session_token, char *aws_region) | ||
{ | ||
char profile_line[32]; | ||
char buffer[128]; | ||
char buffer[4096]; | ||
const char *setting_names[] = { | ||
"region", | ||
"aws_access_key_id", | ||
"aws_secret_access_key", | ||
"aws_session_token", | ||
}; | ||
char *const setting_pointers[] = { | ||
aws_region, | ||
key_id, | ||
access_key, | ||
session_token, | ||
}; | ||
unsigned setting_count = 3; | ||
unsigned setting_count = 4; | ||
herr_t ret_value = SUCCEED; | ||
unsigned setting_i = 0; | ||
int found_setting = 0; | ||
|
@@ -1585,19 +1587,22 @@ H5FD__s3comms_load_aws_creds_from_file(FILE *file, const char *profile_name, cha | |
|
||
/* Look for start of profile */ | ||
do { | ||
memset(buffer, 0, 128); | ||
/* clear buffer */ | ||
memset(buffer, 0, 4096); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to replace repeated uses of 4096 with a single |
||
|
||
line_buffer = fgets(line_buffer, 128, file); | ||
if (line_buffer == NULL) | ||
line_buffer = fgets(line_buffer, 4096, file); | ||
if (line_buffer == NULL) /* reached end of file */ | ||
goto done; | ||
} while (strncmp(line_buffer, profile_line, strlen(profile_line))); | ||
|
||
/* Extract credentials from lines */ | ||
do { | ||
memset(buffer, 0, 128); | ||
/* clear buffer and flag */ | ||
memset(buffer, 0, 4096); | ||
found_setting = 0; | ||
|
||
line_buffer = fgets(line_buffer, 128, file); | ||
/* collect a line from file */ | ||
line_buffer = fgets(line_buffer, 4096, file); | ||
if (line_buffer == NULL) | ||
goto done; /* end of file */ | ||
|
||
|
@@ -1648,6 +1653,78 @@ H5FD__s3comms_load_aws_creds_from_file(FILE *file, const char *profile_name, cha | |
FUNC_LEAVE_NOAPI(ret_value) | ||
} /* end H5FD__s3comms_load_aws_creds_from_file() */ | ||
|
||
/*----------------------------------------------------------------------------- | ||
* | ||
* Function: H5FD__s3comms_load_aws_creds_from_env() | ||
* | ||
* Purpose: | ||
* | ||
* Get aws credentials from environment variables AWS_ACCESS_KEY_ID, | ||
* AWS_SECRET_ACCESS_KEY, AWS_REGION and AWS_SESSION_TOKEN. | ||
* Values from these environment variables will override any values | ||
* for corresponding variables loaded from credentials and configuration | ||
* files. | ||
* | ||
* Values for AWS_PROFILE and AWS_MAX_ATTEMPTS are not currently obtained. | ||
* | ||
* Return: SUCCEED/FAIL | ||
* | ||
*/ | ||
static herr_t | ||
H5FD__s3comms_load_aws_creds_from_env(char *key_id, char *secret_access_key, char *session_token, | ||
char *aws_region) | ||
{ | ||
herr_t ret_value = SUCCEED; | ||
char *key_id_env = NULL; | ||
char *secret_access_key_env = NULL; | ||
char *session_token_env = NULL; | ||
char *aws_region_env = NULL; | ||
|
||
FUNC_ENTER_PACKAGE | ||
|
||
/* AWS_ACCESS_KEY_ID values are typically 16 or 20 characters, with up to 128 allowed. | ||
* Difference in size between the one from the environment and one in cred files | ||
* requires some special handling. | ||
*/ | ||
key_id_env = getenv("AWS_ACCESS_KEY_ID"); | ||
if (key_id_env != NULL && key_id_env[0] != '\0') { | ||
if (strlen(key_id) == 0 || strncmp(key_id, key_id_env, strlen(key_id)) != 0) | ||
strncpy(key_id, key_id_env, strlen(key_id_env)); | ||
key_id[strlen(key_id_env)] = '\0'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason to add a null-terminator to the existing |
||
} | ||
|
||
/* AWS_SECRET_ACCESS_KEY values are 40 characters */ | ||
secret_access_key_env = getenv("AWS_SECRET_ACCESS_KEY"); | ||
if (secret_access_key_env != NULL && secret_access_key_env[0] != '\0') { | ||
if (strlen(secret_access_key) == 0 || | ||
strncmp(secret_access_key, secret_access_key_env, strlen(secret_access_key)) != 0) { | ||
strncpy(secret_access_key, secret_access_key_env, strlen(secret_access_key_env)); | ||
secret_access_key[strlen(secret_access_key_env)] = '\0'; | ||
} | ||
} | ||
|
||
/* AWS_SESSION_TOKEN values are unbounded, but for now assume < 4096 */ | ||
session_token_env = getenv("AWS_SESSION_TOKEN"); | ||
if (session_token_env != NULL && session_token_env[0] != '\0') { | ||
if (strlen(session_token) == 0 || | ||
strncmp(session_token, session_token_env, strlen(session_token_env)) != 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this check for whether to replace the provided session token could produce incorrect behavior if the environment variable is a prefix of the session token from config/credentials files. (e.g. env var = There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would also apply to the key and region. I think it's necessary to either take the longer length or just use |
||
strncpy(session_token, session_token_env, strlen(session_token_env)); | ||
session_token[strlen(session_token_env)] = '\0'; | ||
} | ||
} | ||
|
||
/* AWS_REGION values are 9 - ~12 characters */ | ||
aws_region_env = getenv("AWS_REGION"); | ||
if (aws_region_env != NULL && aws_region_env[0] != '\0') { | ||
if (strlen(aws_region) == 0 || strncmp(aws_region, aws_region_env, strlen(aws_region)) != 0) { | ||
strncpy(aws_region, aws_region_env, strlen(aws_region_env)); | ||
aws_region[strlen(aws_region_env)] = '\0'; | ||
} | ||
} | ||
|
||
FUNC_LEAVE_NOAPI(ret_value) | ||
} | ||
|
||
/*---------------------------------------------------------------------------- | ||
* | ||
* Function: H5FD_s3comms_load_aws_profile() | ||
|
@@ -1679,7 +1756,7 @@ H5FD__s3comms_load_aws_creds_from_file(FILE *file, const char *profile_name, cha | |
*/ | ||
herr_t | ||
H5FD_s3comms_load_aws_profile(const char *profile_name, char *key_id_out, char *secret_access_key_out, | ||
char *aws_region_out) | ||
char *session_token_out, char *aws_region_out) | ||
{ | ||
herr_t ret_value = SUCCEED; | ||
FILE *credfile = NULL; | ||
|
@@ -1703,8 +1780,8 @@ H5FD_s3comms_load_aws_profile(const char *profile_name, char *key_id_out, char * | |
credfile = fopen(filepath, "r"); | ||
if (credfile != NULL) { | ||
if (H5FD__s3comms_load_aws_creds_from_file(credfile, profile_name, key_id_out, secret_access_key_out, | ||
aws_region_out) == FAIL) | ||
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unable to load from aws credentials"); | ||
session_token_out, aws_region_out) == FAIL) | ||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to load from aws credentials"); | ||
if (fclose(credfile) == EOF) | ||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close credentials file"); | ||
credfile = NULL; | ||
|
@@ -1719,13 +1796,20 @@ H5FD_s3comms_load_aws_profile(const char *profile_name, char *key_id_out, char * | |
if (H5FD__s3comms_load_aws_creds_from_file( | ||
credfile, profile_name, (*key_id_out == 0) ? key_id_out : NULL, | ||
(*secret_access_key_out == 0) ? secret_access_key_out : NULL, | ||
(*session_token_out == 0) ? session_token_out : NULL, | ||
(*aws_region_out == 0) ? aws_region_out : NULL) == FAIL) | ||
HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unable to load from aws config"); | ||
if (fclose(credfile) == EOF) | ||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close config file"); | ||
credfile = NULL; | ||
} | ||
|
||
/* Check for credentials in environment variables. Environment variables will override | ||
* credentials from credentials/config files and just load them if there were none in | ||
* the files. */ | ||
ret_value = H5FD__s3comms_load_aws_creds_from_env(key_id_out, secret_access_key_out, session_token_out, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine not use |
||
aws_region_out); | ||
|
||
/* Fail if not all three settings were loaded */ | ||
if (*key_id_out == 0 || *secret_access_key_out == 0 || *aws_region_out == 0) | ||
ret_value = FAIL; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should add 'session token' to the comment for this function describing everything used for the comparison