1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include <aws/testing/aws_test_harness.h>
7
8 #include "shared_credentials_test_definitions.h"
9 #include <aws/auth/credentials.h>
10 #include <aws/auth/private/credentials_utils.h>
11 #include <aws/common/clock.h>
12 #include <aws/common/condition_variable.h>
13 #include <aws/common/date_time.h>
14 #include <aws/common/environment.h>
15 #include <aws/common/string.h>
16 #include <aws/common/thread.h>
17 #include <aws/http/request_response.h>
18 #include <aws/http/status_code.h>
19 #include <aws/io/channel_bootstrap.h>
20 #include <aws/io/event_loop.h>
21 #include <aws/io/logging.h>
22 #include <aws/io/socket.h>
23 #include <aws/io/stream.h>
24 #include <aws/io/tls_channel_handler.h>
25
26 static struct aws_mock_sts_web_identity_tester {
27 struct aws_tls_ctx *tls_ctx;
28
29 struct aws_byte_buf request_body;
30
31 struct aws_array_list response_data_callbacks;
32 bool is_connection_acquire_successful;
33 bool is_request_successful;
34
35 struct aws_mutex lock;
36 struct aws_condition_variable signal;
37
38 struct aws_credentials *credentials;
39 bool has_received_credentials_callback;
40 bool has_received_shutdown_callback;
41
42 int attempts;
43 int response_code;
44 int error_code;
45 } s_tester;
46
s_on_shutdown_complete(void * user_data)47 static void s_on_shutdown_complete(void *user_data) {
48 (void)user_data;
49
50 aws_mutex_lock(&s_tester.lock);
51 s_tester.has_received_shutdown_callback = true;
52 aws_mutex_unlock(&s_tester.lock);
53
54 aws_condition_variable_notify_one(&s_tester.signal);
55 }
56
s_has_tester_received_shutdown_callback(void * user_data)57 static bool s_has_tester_received_shutdown_callback(void *user_data) {
58 (void)user_data;
59
60 return s_tester.has_received_shutdown_callback;
61 }
62
s_aws_wait_for_provider_shutdown_callback(void)63 static void s_aws_wait_for_provider_shutdown_callback(void) {
64 aws_mutex_lock(&s_tester.lock);
65 aws_condition_variable_wait_pred(&s_tester.signal, &s_tester.lock, s_has_tester_received_shutdown_callback, NULL);
66 aws_mutex_unlock(&s_tester.lock);
67 }
68
69 struct mock_connection_manager {
70 struct aws_allocator *allocator;
71 aws_http_connection_manager_shutdown_complete_fn *shutdown_complete_callback;
72 void *shutdown_complete_user_data;
73 };
74
s_aws_http_connection_manager_new_mock(struct aws_allocator * allocator,struct aws_http_connection_manager_options * options)75 static struct aws_http_connection_manager *s_aws_http_connection_manager_new_mock(
76 struct aws_allocator *allocator,
77 struct aws_http_connection_manager_options *options) {
78
79 struct mock_connection_manager *mock_manager = aws_mem_calloc(allocator, 1, sizeof(struct mock_connection_manager));
80 mock_manager->allocator = allocator;
81 mock_manager->shutdown_complete_callback = options->shutdown_complete_callback;
82 mock_manager->shutdown_complete_user_data = options->shutdown_complete_user_data;
83 return (struct aws_http_connection_manager *)mock_manager;
84 }
85
s_aws_http_connection_manager_release_mock(struct aws_http_connection_manager * manager)86 static void s_aws_http_connection_manager_release_mock(struct aws_http_connection_manager *manager) {
87 struct mock_connection_manager *mock_manager = (struct mock_connection_manager *)manager;
88 mock_manager->shutdown_complete_callback(mock_manager->shutdown_complete_user_data);
89 aws_mem_release(mock_manager->allocator, mock_manager);
90 }
91
s_aws_http_connection_manager_acquire_connection_mock(struct aws_http_connection_manager * manager,aws_http_connection_manager_on_connection_setup_fn * callback,void * user_data)92 static void s_aws_http_connection_manager_acquire_connection_mock(
93 struct aws_http_connection_manager *manager,
94 aws_http_connection_manager_on_connection_setup_fn *callback,
95 void *user_data) {
96
97 (void)manager;
98 (void)callback;
99 (void)user_data;
100
101 if (s_tester.is_connection_acquire_successful) {
102 callback((struct aws_http_connection *)1, AWS_OP_SUCCESS, user_data);
103 } else {
104 aws_raise_error(AWS_ERROR_HTTP_UNKNOWN);
105 callback(NULL, AWS_OP_ERR, user_data);
106 }
107 }
108
s_aws_http_connection_manager_release_connection_mock(struct aws_http_connection_manager * manager,struct aws_http_connection * connection)109 static int s_aws_http_connection_manager_release_connection_mock(
110 struct aws_http_connection_manager *manager,
111 struct aws_http_connection *connection) {
112
113 (void)manager;
114 (void)connection;
115
116 return AWS_OP_SUCCESS;
117 }
118
s_invoke_mock_request_callbacks(const struct aws_http_make_request_options * options,struct aws_array_list * data_callbacks,bool is_request_successful)119 static void s_invoke_mock_request_callbacks(
120 const struct aws_http_make_request_options *options,
121 struct aws_array_list *data_callbacks,
122 bool is_request_successful) {
123
124 size_t data_callback_count = aws_array_list_length(data_callbacks);
125
126 struct aws_http_header headers[1];
127 AWS_ZERO_ARRAY(headers);
128
129 headers[0].name = aws_byte_cursor_from_c_str("some-header");
130 headers[0].value = aws_byte_cursor_from_c_str("value");
131 options->on_response_headers(
132 (struct aws_http_stream *)1, AWS_HTTP_HEADER_BLOCK_MAIN, headers, 1, options->user_data);
133
134 if (options->on_response_header_block_done) {
135 options->on_response_header_block_done(
136 (struct aws_http_stream *)1, data_callback_count > 0, options->user_data);
137 }
138
139 for (size_t i = 0; i < data_callback_count; ++i) {
140 struct aws_byte_cursor data_callback_cursor;
141 if (aws_array_list_get_at(data_callbacks, &data_callback_cursor, i)) {
142 continue;
143 }
144
145 options->on_response_body((struct aws_http_stream *)1, &data_callback_cursor, options->user_data);
146 }
147
148 options->on_complete(
149 (struct aws_http_stream *)1,
150 is_request_successful ? AWS_ERROR_SUCCESS : AWS_ERROR_HTTP_UNKNOWN,
151 options->user_data);
152 }
153
s_aws_http_connection_make_request_mock(struct aws_http_connection * client_connection,const struct aws_http_make_request_options * options)154 static struct aws_http_stream *s_aws_http_connection_make_request_mock(
155 struct aws_http_connection *client_connection,
156 const struct aws_http_make_request_options *options) {
157
158 (void)client_connection;
159 (void)options;
160
161 struct aws_byte_cursor path;
162 AWS_ZERO_STRUCT(path);
163 struct aws_input_stream *body_stream = aws_http_message_get_body_stream(options->request);
164 struct aws_allocator *allocator = s_tester.request_body.allocator;
165 aws_byte_buf_clean_up(&s_tester.request_body);
166 aws_byte_buf_init(&s_tester.request_body, allocator, 256);
167 aws_input_stream_read(body_stream, &s_tester.request_body);
168 s_invoke_mock_request_callbacks(options, &s_tester.response_data_callbacks, s_tester.is_request_successful);
169
170 s_tester.attempts++;
171 return (struct aws_http_stream *)1;
172 }
173
s_aws_http_stream_activate_mock(struct aws_http_stream * stream)174 static int s_aws_http_stream_activate_mock(struct aws_http_stream *stream) {
175 (void)stream;
176 return AWS_OP_SUCCESS;
177 }
178
s_aws_http_stream_get_incoming_response_status_mock(const struct aws_http_stream * stream,int * out_status_code)179 static int s_aws_http_stream_get_incoming_response_status_mock(
180 const struct aws_http_stream *stream,
181 int *out_status_code) {
182 (void)stream;
183
184 if (s_tester.response_code) {
185 *out_status_code = s_tester.response_code;
186 } else {
187 *out_status_code = AWS_HTTP_STATUS_CODE_200_OK;
188 }
189
190 return AWS_OP_SUCCESS;
191 }
192
s_aws_http_stream_release_mock(struct aws_http_stream * stream)193 static void s_aws_http_stream_release_mock(struct aws_http_stream *stream) {
194 (void)stream;
195 }
196
s_aws_http_connection_close_mock(struct aws_http_connection * connection)197 static void s_aws_http_connection_close_mock(struct aws_http_connection *connection) {
198 (void)connection;
199 }
200
s_aws_http_stream_get_connection_mock(const struct aws_http_stream * stream)201 static struct aws_http_connection *s_aws_http_stream_get_connection_mock(const struct aws_http_stream *stream) {
202 (void)stream;
203 return (struct aws_http_connection *)1;
204 }
205
206 static struct aws_auth_http_system_vtable s_mock_function_table = {
207 .aws_http_connection_manager_new = s_aws_http_connection_manager_new_mock,
208 .aws_http_connection_manager_release = s_aws_http_connection_manager_release_mock,
209 .aws_http_connection_manager_acquire_connection = s_aws_http_connection_manager_acquire_connection_mock,
210 .aws_http_connection_manager_release_connection = s_aws_http_connection_manager_release_connection_mock,
211 .aws_http_connection_make_request = s_aws_http_connection_make_request_mock,
212 .aws_http_stream_activate = s_aws_http_stream_activate_mock,
213 .aws_http_stream_get_connection = s_aws_http_stream_get_connection_mock,
214 .aws_http_stream_get_incoming_response_status = s_aws_http_stream_get_incoming_response_status_mock,
215 .aws_http_stream_release = s_aws_http_stream_release_mock,
216 .aws_http_connection_close = s_aws_http_connection_close_mock};
217
218 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_foo_profile, "foo");
219 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_region_env, "AWS_DEFAULT_REGION");
220 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_role_arn_env, "AWS_ROLE_ARN");
221 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_role_session_name_env, "AWS_ROLE_SESSION_NAME");
222 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_token_file_path_env, "AWS_WEB_IDENTITY_TOKEN_FILE");
223 AWS_STATIC_STRING_FROM_LITERAL(s_sts_web_identity_token_contents, "my-test-token-contents-123-abc-xyz");
224
s_aws_sts_web_identity_test_unset_env_parameters(void)225 static int s_aws_sts_web_identity_test_unset_env_parameters(void) {
226 ASSERT_TRUE(aws_unset_environment_value(s_sts_web_identity_region_env) == AWS_OP_SUCCESS);
227 ASSERT_TRUE(aws_unset_environment_value(s_sts_web_identity_role_arn_env) == AWS_OP_SUCCESS);
228 ASSERT_TRUE(aws_unset_environment_value(s_sts_web_identity_role_session_name_env) == AWS_OP_SUCCESS);
229 ASSERT_TRUE(aws_unset_environment_value(s_sts_web_identity_token_file_path_env) == AWS_OP_SUCCESS);
230
231 return AWS_OP_SUCCESS;
232 }
233
s_aws_sts_web_identity_test_init_env_parameters(struct aws_allocator * allocator,const char * region,const char * role_arn,const char * role_session_name,const char * web_identity_token_file)234 static int s_aws_sts_web_identity_test_init_env_parameters(
235 struct aws_allocator *allocator,
236 const char *region,
237 const char *role_arn,
238 const char *role_session_name,
239 const char *web_identity_token_file) {
240
241 struct aws_string *region_str = aws_string_new_from_c_str(allocator, region);
242 ASSERT_TRUE(region_str != NULL);
243 ASSERT_TRUE(aws_set_environment_value(s_sts_web_identity_region_env, region_str) == AWS_OP_SUCCESS);
244 aws_string_destroy(region_str);
245
246 struct aws_string *role_arn_str = aws_string_new_from_c_str(allocator, role_arn);
247 ASSERT_TRUE(role_arn_str != NULL);
248 ASSERT_TRUE(aws_set_environment_value(s_sts_web_identity_role_arn_env, role_arn_str) == AWS_OP_SUCCESS);
249 aws_string_destroy(role_arn_str);
250
251 struct aws_string *role_session_name_str = aws_string_new_from_c_str(allocator, role_session_name);
252 ASSERT_TRUE(role_session_name_str != NULL);
253 ASSERT_TRUE(
254 aws_set_environment_value(s_sts_web_identity_role_session_name_env, role_session_name_str) == AWS_OP_SUCCESS);
255 aws_string_destroy(role_session_name_str);
256
257 struct aws_string *web_identity_token_file_str = aws_string_new_from_c_str(allocator, web_identity_token_file);
258 ASSERT_TRUE(web_identity_token_file_str != NULL);
259 ASSERT_TRUE(
260 aws_set_environment_value(s_sts_web_identity_token_file_path_env, web_identity_token_file_str) ==
261 AWS_OP_SUCCESS);
262 aws_string_destroy(web_identity_token_file_str);
263
264 return AWS_OP_SUCCESS;
265 }
266
s_aws_sts_web_identity_test_init_config_profile(struct aws_allocator * allocator,const struct aws_string * config_contents)267 static int s_aws_sts_web_identity_test_init_config_profile(
268 struct aws_allocator *allocator,
269 const struct aws_string *config_contents) {
270
271 struct aws_string *config_file_path_str = aws_create_process_unique_file_name(allocator);
272 ASSERT_TRUE(config_file_path_str != NULL);
273 ASSERT_TRUE(aws_create_profile_file(config_file_path_str, config_contents) == AWS_OP_SUCCESS);
274
275 ASSERT_TRUE(
276 aws_set_environment_value(s_default_config_path_env_variable_name, config_file_path_str) == AWS_OP_SUCCESS);
277
278 ASSERT_TRUE(
279 aws_set_environment_value(s_default_profile_env_variable_name, s_sts_web_identity_foo_profile) ==
280 AWS_OP_SUCCESS);
281
282 aws_string_destroy(config_file_path_str);
283 return AWS_OP_SUCCESS;
284 }
285
s_aws_sts_web_identity_tester_init(struct aws_allocator * allocator)286 static int s_aws_sts_web_identity_tester_init(struct aws_allocator *allocator) {
287 aws_auth_library_init(allocator);
288
289 struct aws_tls_ctx_options tls_options;
290 aws_tls_ctx_options_init_default_client(&tls_options, allocator);
291 s_tester.tls_ctx = aws_tls_client_ctx_new(allocator, &tls_options);
292 ASSERT_NOT_NULL(s_tester.tls_ctx);
293
294 if (aws_array_list_init_dynamic(&s_tester.response_data_callbacks, allocator, 10, sizeof(struct aws_byte_cursor))) {
295 return AWS_OP_ERR;
296 }
297
298 if (aws_byte_buf_init(&s_tester.request_body, allocator, 256)) {
299 return AWS_OP_ERR;
300 }
301
302 if (aws_mutex_init(&s_tester.lock)) {
303 return AWS_OP_ERR;
304 }
305
306 if (aws_condition_variable_init(&s_tester.signal)) {
307 return AWS_OP_ERR;
308 }
309
310 /* default to everything successful */
311 s_tester.is_connection_acquire_successful = true;
312 s_tester.is_request_successful = true;
313
314 return AWS_OP_SUCCESS;
315 }
316
s_aws_sts_web_identity_tester_cleanup(void)317 static void s_aws_sts_web_identity_tester_cleanup(void) {
318 aws_tls_ctx_release(s_tester.tls_ctx);
319 aws_array_list_clean_up(&s_tester.response_data_callbacks);
320 aws_byte_buf_clean_up(&s_tester.request_body);
321 aws_condition_variable_clean_up(&s_tester.signal);
322 aws_mutex_clean_up(&s_tester.lock);
323 aws_credentials_release(s_tester.credentials);
324 aws_auth_library_clean_up();
325 }
326
s_has_tester_received_credentials_callback(void * user_data)327 static bool s_has_tester_received_credentials_callback(void *user_data) {
328 (void)user_data;
329
330 return s_tester.has_received_credentials_callback;
331 }
332
s_aws_wait_for_credentials_result(void)333 static void s_aws_wait_for_credentials_result(void) {
334 aws_mutex_lock(&s_tester.lock);
335 aws_condition_variable_wait_pred(
336 &s_tester.signal, &s_tester.lock, s_has_tester_received_credentials_callback, NULL);
337 aws_mutex_unlock(&s_tester.lock);
338 }
339
s_get_credentials_callback(struct aws_credentials * credentials,int error_code,void * user_data)340 static void s_get_credentials_callback(struct aws_credentials *credentials, int error_code, void *user_data) {
341 (void)user_data;
342
343 aws_mutex_lock(&s_tester.lock);
344 s_tester.has_received_credentials_callback = true;
345 s_tester.credentials = credentials;
346 s_tester.error_code = error_code;
347 if (credentials != NULL) {
348 aws_credentials_acquire(credentials);
349 }
350 aws_condition_variable_notify_one(&s_tester.signal);
351 aws_mutex_unlock(&s_tester.lock);
352 }
353
s_credentials_provider_sts_web_identity_new_destroy_from_env(struct aws_allocator * allocator,void * ctx)354 static int s_credentials_provider_sts_web_identity_new_destroy_from_env(struct aws_allocator *allocator, void *ctx) {
355 (void)ctx;
356
357 s_aws_sts_web_identity_tester_init(allocator);
358
359 s_aws_sts_web_identity_test_unset_env_parameters();
360
361 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
362 ASSERT_TRUE(token_file_path_str != NULL);
363 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
364
365 s_aws_sts_web_identity_test_init_env_parameters(
366 allocator,
367 "us-east-1",
368 "arn:aws:iam::1234567890:role/test-arn",
369 "9876543210",
370 aws_string_c_str(token_file_path_str));
371 aws_string_destroy(token_file_path_str);
372
373 struct aws_credentials_provider_sts_web_identity_options options = {
374 .bootstrap = NULL,
375 .tls_ctx = s_tester.tls_ctx,
376 .function_table = &s_mock_function_table,
377 .shutdown_options =
378 {
379 .shutdown_callback = s_on_shutdown_complete,
380 .shutdown_user_data = NULL,
381 },
382 };
383
384 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
385 aws_credentials_provider_release(provider);
386
387 s_aws_wait_for_provider_shutdown_callback();
388
389 s_aws_sts_web_identity_tester_cleanup();
390
391 return 0;
392 }
393 AWS_TEST_CASE(
394 credentials_provider_sts_web_identity_new_destroy_from_env,
395 s_credentials_provider_sts_web_identity_new_destroy_from_env);
396
397 AWS_STATIC_STRING_FROM_LITERAL(
398 s_sts_web_identity_config_file_contents,
399 "[profile default]\n"
400 "region=us-east-1\n"
401 "role_arn=arn:aws:iam::1111111111:role/test-arn\n"
402 "role_session_name=2222222222\n"
403 "web_identity_token_file=/some/unreachable/path/toklen_file\n"
404 "[profile foo]\n"
405 "region=us-west-2\n"
406 "role_arn=arn:aws:iam::3333333333:role/test-arn\n"
407 "role_session_name=4444444444\n"
408 "web_identity_token_file=");
409
s_credentials_provider_sts_web_identity_new_destroy_from_config(struct aws_allocator * allocator,void * ctx)410 static int s_credentials_provider_sts_web_identity_new_destroy_from_config(struct aws_allocator *allocator, void *ctx) {
411 (void)ctx;
412
413 s_aws_sts_web_identity_tester_init(allocator);
414
415 s_aws_sts_web_identity_test_unset_env_parameters();
416
417 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
418 ASSERT_TRUE(token_file_path_str != NULL);
419 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
420
421 struct aws_byte_buf content_buf;
422 struct aws_byte_buf existing_content =
423 aws_byte_buf_from_c_str(aws_string_c_str(s_sts_web_identity_config_file_contents));
424 aws_byte_buf_init_copy(&content_buf, allocator, &existing_content);
425 struct aws_byte_cursor cursor = aws_byte_cursor_from_string(token_file_path_str);
426 ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS);
427 cursor = aws_byte_cursor_from_c_str("\n");
428 ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS);
429 aws_string_destroy(token_file_path_str);
430
431 struct aws_string *config_file_contents = aws_string_new_from_array(allocator, content_buf.buffer, content_buf.len);
432 ASSERT_TRUE(config_file_contents != NULL);
433 aws_byte_buf_clean_up(&content_buf);
434
435 s_aws_sts_web_identity_test_init_config_profile(allocator, config_file_contents);
436 aws_string_destroy(config_file_contents);
437
438 struct aws_credentials_provider_sts_web_identity_options options = {
439 .bootstrap = NULL,
440 .tls_ctx = s_tester.tls_ctx,
441 .function_table = &s_mock_function_table,
442 .shutdown_options =
443 {
444 .shutdown_callback = s_on_shutdown_complete,
445 .shutdown_user_data = NULL,
446 },
447 };
448
449 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
450 aws_credentials_provider_release(provider);
451
452 s_aws_wait_for_provider_shutdown_callback();
453
454 s_aws_sts_web_identity_tester_cleanup();
455
456 return 0;
457 }
458 AWS_TEST_CASE(
459 credentials_provider_sts_web_identity_new_destroy_from_config,
460 s_credentials_provider_sts_web_identity_new_destroy_from_config);
461
s_credentials_provider_sts_web_identity_new_failed_without_env_and_config(struct aws_allocator * allocator,void * ctx)462 static int s_credentials_provider_sts_web_identity_new_failed_without_env_and_config(
463 struct aws_allocator *allocator,
464 void *ctx) {
465 (void)ctx;
466
467 s_aws_sts_web_identity_tester_init(allocator);
468
469 struct aws_string *empty_content = aws_string_new_from_c_str(allocator, "");
470 ASSERT_TRUE(empty_content != NULL);
471 s_aws_sts_web_identity_test_init_config_profile(allocator, empty_content);
472 aws_string_destroy(empty_content);
473
474 s_aws_sts_web_identity_test_unset_env_parameters();
475
476 ASSERT_TRUE(aws_unset_environment_value(s_default_profile_env_variable_name) == AWS_OP_SUCCESS);
477
478 struct aws_credentials_provider_sts_web_identity_options options = {
479 .bootstrap = NULL,
480 .tls_ctx = s_tester.tls_ctx,
481 .function_table = &s_mock_function_table,
482 .shutdown_options =
483 {
484 .shutdown_callback = s_on_shutdown_complete,
485 .shutdown_user_data = NULL,
486 },
487 };
488
489 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
490 ASSERT_TRUE(provider == NULL);
491
492 s_aws_sts_web_identity_tester_cleanup();
493
494 return 0;
495 }
496
497 AWS_TEST_CASE(
498 credentials_provider_sts_web_identity_new_failed_without_env_and_config,
499 s_credentials_provider_sts_web_identity_new_failed_without_env_and_config);
500
501 AWS_STATIC_STRING_FROM_LITERAL(
502 s_expected_sts_web_identity_body_message,
503 "Action=AssumeRoleWithWebIdentity&Version=2011-06-15"
504 "&RoleArn=arn%3Aaws%3Aiam%3A%3A1234567890%3Arole%2Ftest-arn&RoleSessionName=9876543210&WebIdentityToken=my-test-"
505 "token-contents-123-abc-xyz");
506 AWS_STATIC_STRING_FROM_LITERAL(
507 s_expected_sts_web_identity_body_message_config,
508 "Action=AssumeRoleWithWebIdentity&Version=2011-06-15"
509 "&RoleArn=arn%3Aaws%3Aiam%3A%3A3333333333%3Arole%2Ftest-arn&RoleSessionName=4444444444&WebIdentityToken=my-test-"
510 "token-contents-123-abc-xyz");
511
512 AWS_STATIC_STRING_FROM_LITERAL(
513 s_good_response,
514 "<AssumeRoleWithWebIdentityResponse>"
515 " <AssumeRoleWithWebIdentityResult>"
516 " <AssumedRoleUser>"
517 " <Arn>arn:aws:sts::123456789012:assumed-role/FederatedWebIdentityRole/app1</Arn>"
518 " <AssumedRoleId>AROACLKWSDQRAOEXAMPLE:app1</AssumedRoleId>"
519 " </AssumedRoleUser>"
520 " <Credentials>"
521 " <SessionToken>TokenSuccess</SessionToken>"
522 " <SecretAccessKey>SuccessfulSecret</SecretAccessKey>"
523 " <Expiration>2020-02-25T06:03:31Z</Expiration>"
524 " <AccessKeyId>SuccessfulAccessKey</AccessKeyId>"
525 " </Credentials>"
526 " <Provider>www.amazon.com</Provider>"
527 " </AssumeRoleWithWebIdentityResult>"
528 " <ResponseMetadata>"
529 " <RequestId>ad4156e9-bce1-11e2-82e6-6b6efEXAMPLE</RequestId>"
530 " </ResponseMetadata>"
531 "</AssumeRoleWithWebIdentityResponse>");
532 AWS_STATIC_STRING_FROM_LITERAL(s_good_access_key_id, "SuccessfulAccessKey");
533 AWS_STATIC_STRING_FROM_LITERAL(s_good_secret_access_key, "SuccessfulSecret");
534 AWS_STATIC_STRING_FROM_LITERAL(s_good_session_token, "TokenSuccess");
535 AWS_STATIC_STRING_FROM_LITERAL(s_good_response_expiration, "2020-02-25T06:03:31Z");
536
s_verify_credentials(bool request_made,bool from_config,bool got_credentials,int expected_attempts)537 static int s_verify_credentials(bool request_made, bool from_config, bool got_credentials, int expected_attempts) {
538
539 if (request_made) {
540 if (from_config) {
541 ASSERT_CURSOR_VALUE_STRING_EQUALS(
542 aws_byte_cursor_from_buf(&s_tester.request_body), s_expected_sts_web_identity_body_message_config);
543 } else {
544 ASSERT_CURSOR_VALUE_STRING_EQUALS(
545 aws_byte_cursor_from_buf(&s_tester.request_body), s_expected_sts_web_identity_body_message);
546 }
547 }
548
549 ASSERT_TRUE(s_tester.has_received_credentials_callback);
550
551 if (got_credentials) {
552 ASSERT_TRUE(s_tester.credentials != NULL);
553 ASSERT_CURSOR_VALUE_STRING_EQUALS(
554 aws_credentials_get_access_key_id(s_tester.credentials), s_good_access_key_id);
555 ASSERT_CURSOR_VALUE_STRING_EQUALS(
556 aws_credentials_get_secret_access_key(s_tester.credentials), s_good_secret_access_key);
557 ASSERT_CURSOR_VALUE_STRING_EQUALS(
558 aws_credentials_get_session_token(s_tester.credentials), s_good_session_token);
559 } else {
560 ASSERT_TRUE(s_tester.credentials == NULL);
561 }
562
563 ASSERT_TRUE(s_tester.attempts == expected_attempts);
564
565 return AWS_OP_SUCCESS;
566 }
567
s_credentials_provider_sts_web_identity_connect_failure(struct aws_allocator * allocator,void * ctx)568 static int s_credentials_provider_sts_web_identity_connect_failure(struct aws_allocator *allocator, void *ctx) {
569 (void)ctx;
570
571 s_aws_sts_web_identity_tester_init(allocator);
572 s_tester.is_connection_acquire_successful = false;
573
574 s_aws_sts_web_identity_test_unset_env_parameters();
575
576 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
577 ASSERT_TRUE(token_file_path_str != NULL);
578 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
579
580 s_aws_sts_web_identity_test_init_env_parameters(
581 allocator,
582 "us-east-1",
583 "arn:aws:iam::1234567890:role/test-arn",
584 "9876543210",
585 aws_string_c_str(token_file_path_str));
586 aws_string_destroy(token_file_path_str);
587
588 struct aws_credentials_provider_sts_web_identity_options options = {
589 .bootstrap = NULL,
590 .tls_ctx = s_tester.tls_ctx,
591 .function_table = &s_mock_function_table,
592 .shutdown_options =
593 {
594 .shutdown_callback = s_on_shutdown_complete,
595 .shutdown_user_data = NULL,
596 },
597 };
598
599 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
600
601 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
602
603 s_aws_wait_for_credentials_result();
604
605 ASSERT_SUCCESS(s_verify_credentials(
606 false /*no request*/, false /*from config*/, false /*get creds*/, 0 /*expected attempts*/));
607
608 aws_credentials_provider_release(provider);
609
610 s_aws_wait_for_provider_shutdown_callback();
611
612 s_aws_sts_web_identity_tester_cleanup();
613
614 return 0;
615 }
616 AWS_TEST_CASE(
617 credentials_provider_sts_web_identity_connect_failure,
618 s_credentials_provider_sts_web_identity_connect_failure);
619
s_credentials_provider_sts_web_identity_request_failure(struct aws_allocator * allocator,void * ctx)620 static int s_credentials_provider_sts_web_identity_request_failure(struct aws_allocator *allocator, void *ctx) {
621 (void)ctx;
622
623 s_aws_sts_web_identity_tester_init(allocator);
624 s_tester.is_request_successful = false;
625
626 s_aws_sts_web_identity_test_unset_env_parameters();
627
628 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
629 ASSERT_TRUE(token_file_path_str != NULL);
630 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
631
632 s_aws_sts_web_identity_test_init_env_parameters(
633 allocator,
634 "us-east-1",
635 "arn:aws:iam::1234567890:role/test-arn",
636 "9876543210",
637 aws_string_c_str(token_file_path_str));
638 aws_string_destroy(token_file_path_str);
639
640 struct aws_credentials_provider_sts_web_identity_options options = {
641 .bootstrap = NULL,
642 .tls_ctx = s_tester.tls_ctx,
643 .function_table = &s_mock_function_table,
644 .shutdown_options =
645 {
646 .shutdown_callback = s_on_shutdown_complete,
647 .shutdown_user_data = NULL,
648 },
649 };
650
651 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
652
653 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
654
655 s_aws_wait_for_credentials_result();
656
657 ASSERT_SUCCESS(s_verify_credentials(
658 true /*request made*/, false /*from config*/, false /*get creds*/, 1 /*expected attempts*/));
659
660 aws_credentials_provider_release(provider);
661
662 s_aws_wait_for_provider_shutdown_callback();
663
664 s_aws_sts_web_identity_tester_cleanup();
665
666 return 0;
667 }
668 AWS_TEST_CASE(
669 credentials_provider_sts_web_identity_request_failure,
670 s_credentials_provider_sts_web_identity_request_failure);
671
672 AWS_STATIC_STRING_FROM_LITERAL(
673 s_bad_document_response,
674 "<AssumeRoleWithWebIdentityResponse xmlns=\"Not the right doc\">Test</AssumeRoleWithWebIdentityResponse>");
675
s_credentials_provider_sts_web_identity_bad_document_failure(struct aws_allocator * allocator,void * ctx)676 static int s_credentials_provider_sts_web_identity_bad_document_failure(struct aws_allocator *allocator, void *ctx) {
677 (void)ctx;
678
679 s_aws_sts_web_identity_tester_init(allocator);
680
681 s_aws_sts_web_identity_test_unset_env_parameters();
682
683 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
684 ASSERT_TRUE(token_file_path_str != NULL);
685 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
686
687 s_aws_sts_web_identity_test_init_env_parameters(
688 allocator,
689 "us-east-1",
690 "arn:aws:iam::1234567890:role/test-arn",
691 "9876543210",
692 aws_string_c_str(token_file_path_str));
693 aws_string_destroy(token_file_path_str);
694
695 struct aws_byte_cursor bad_document_cursor = aws_byte_cursor_from_string(s_bad_document_response);
696 aws_array_list_push_back(&s_tester.response_data_callbacks, &bad_document_cursor);
697
698 struct aws_credentials_provider_sts_web_identity_options options = {
699 .bootstrap = NULL,
700 .tls_ctx = s_tester.tls_ctx,
701 .function_table = &s_mock_function_table,
702 .shutdown_options =
703 {
704 .shutdown_callback = s_on_shutdown_complete,
705 .shutdown_user_data = NULL,
706 },
707 };
708
709 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
710
711 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
712
713 s_aws_wait_for_credentials_result();
714
715 ASSERT_SUCCESS(s_verify_credentials(
716 true /*request made*/, false /*from config*/, false /*get creds*/, 1 /*expected attempts*/));
717
718 aws_credentials_provider_release(provider);
719
720 s_aws_wait_for_provider_shutdown_callback();
721
722 s_aws_sts_web_identity_tester_cleanup();
723
724 return 0;
725 }
726 AWS_TEST_CASE(
727 credentials_provider_sts_web_identity_bad_document_failure,
728 s_credentials_provider_sts_web_identity_bad_document_failure);
729
730 AWS_STATIC_STRING_FROM_LITERAL(
731 s_retryable_error_response_1,
732 "<Error>"
733 "<Code>IDPCommunicationError</Code>"
734 "<Message>XXX</Message>"
735 "<Resource>YYY</Resource>"
736 "<RequestId>4442587FB7D0A2F9</RequestId>"
737 "</Error>");
738
739 AWS_STATIC_STRING_FROM_LITERAL(
740 s_retryable_error_response_2,
741 "<Error>"
742 "<Code>InvalidIdentityToken</Code>"
743 "<Message>XXX</Message>"
744 "<Resource>YYY</Resource>"
745 "<RequestId>4442587FB7D0A2F9</RequestId>"
746 "</Error>");
747
s_credentials_provider_sts_web_identity_test_retry_error1(struct aws_allocator * allocator,void * ctx)748 static int s_credentials_provider_sts_web_identity_test_retry_error1(struct aws_allocator *allocator, void *ctx) {
749 (void)ctx;
750
751 s_aws_sts_web_identity_tester_init(allocator);
752 s_tester.response_code = AWS_HTTP_STATUS_CODE_400_BAD_REQUEST;
753 s_aws_sts_web_identity_test_unset_env_parameters();
754
755 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
756 ASSERT_TRUE(token_file_path_str != NULL);
757 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
758
759 s_aws_sts_web_identity_test_init_env_parameters(
760 allocator,
761 "us-east-1",
762 "arn:aws:iam::1234567890:role/test-arn",
763 "9876543210",
764 aws_string_c_str(token_file_path_str));
765 aws_string_destroy(token_file_path_str);
766
767 struct aws_byte_cursor bad_document_cursor = aws_byte_cursor_from_string(s_retryable_error_response_1);
768 aws_array_list_push_back(&s_tester.response_data_callbacks, &bad_document_cursor);
769
770 struct aws_credentials_provider_sts_web_identity_options options = {
771 .bootstrap = NULL,
772 .tls_ctx = s_tester.tls_ctx,
773 .function_table = &s_mock_function_table,
774 .shutdown_options =
775 {
776 .shutdown_callback = s_on_shutdown_complete,
777 .shutdown_user_data = NULL,
778 },
779 };
780
781 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
782
783 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
784
785 s_aws_wait_for_credentials_result();
786
787 ASSERT_SUCCESS(s_verify_credentials(
788 true /*request made*/, false /*from config*/, false /*get creds*/, 3 /*expected attempts*/));
789
790 aws_credentials_provider_release(provider);
791
792 s_aws_wait_for_provider_shutdown_callback();
793
794 s_aws_sts_web_identity_tester_cleanup();
795
796 return 0;
797 }
798 AWS_TEST_CASE(
799 credentials_provider_sts_web_identity_test_retry_error1,
800 s_credentials_provider_sts_web_identity_test_retry_error1);
801
s_credentials_provider_sts_web_identity_test_retry_error2(struct aws_allocator * allocator,void * ctx)802 static int s_credentials_provider_sts_web_identity_test_retry_error2(struct aws_allocator *allocator, void *ctx) {
803 (void)ctx;
804
805 s_aws_sts_web_identity_tester_init(allocator);
806 s_tester.response_code = AWS_HTTP_STATUS_CODE_400_BAD_REQUEST;
807 s_aws_sts_web_identity_test_unset_env_parameters();
808
809 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
810 ASSERT_TRUE(token_file_path_str != NULL);
811 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
812
813 s_aws_sts_web_identity_test_init_env_parameters(
814 allocator,
815 "us-east-1",
816 "arn:aws:iam::1234567890:role/test-arn",
817 "9876543210",
818 aws_string_c_str(token_file_path_str));
819 aws_string_destroy(token_file_path_str);
820
821 struct aws_byte_cursor bad_document_cursor = aws_byte_cursor_from_string(s_retryable_error_response_2);
822 aws_array_list_push_back(&s_tester.response_data_callbacks, &bad_document_cursor);
823
824 struct aws_credentials_provider_sts_web_identity_options options = {
825 .bootstrap = NULL,
826 .tls_ctx = s_tester.tls_ctx,
827 .function_table = &s_mock_function_table,
828 .shutdown_options =
829 {
830 .shutdown_callback = s_on_shutdown_complete,
831 .shutdown_user_data = NULL,
832 },
833 };
834
835 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
836
837 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
838
839 s_aws_wait_for_credentials_result();
840
841 ASSERT_SUCCESS(s_verify_credentials(
842 true /*request made*/, false /*from config*/, false /*get creds*/, 3 /*expected attempts*/));
843
844 aws_credentials_provider_release(provider);
845
846 s_aws_wait_for_provider_shutdown_callback();
847
848 s_aws_sts_web_identity_tester_cleanup();
849
850 return 0;
851 }
852 AWS_TEST_CASE(
853 credentials_provider_sts_web_identity_test_retry_error2,
854 s_credentials_provider_sts_web_identity_test_retry_error2);
855
s_credentials_provider_sts_web_identity_basic_success_env(struct aws_allocator * allocator,void * ctx)856 static int s_credentials_provider_sts_web_identity_basic_success_env(struct aws_allocator *allocator, void *ctx) {
857 (void)ctx;
858
859 s_aws_sts_web_identity_tester_init(allocator);
860
861 s_aws_sts_web_identity_test_unset_env_parameters();
862
863 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
864 ASSERT_TRUE(token_file_path_str != NULL);
865 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
866
867 s_aws_sts_web_identity_test_init_env_parameters(
868 allocator,
869 "us-east-1",
870 "arn:aws:iam::1234567890:role/test-arn",
871 "9876543210",
872 aws_string_c_str(token_file_path_str));
873 aws_string_destroy(token_file_path_str);
874
875 struct aws_byte_cursor good_response_cursor = aws_byte_cursor_from_string(s_good_response);
876 aws_array_list_push_back(&s_tester.response_data_callbacks, &good_response_cursor);
877
878 struct aws_credentials_provider_sts_web_identity_options options = {
879 .bootstrap = NULL,
880 .tls_ctx = s_tester.tls_ctx,
881 .function_table = &s_mock_function_table,
882 .shutdown_options =
883 {
884 .shutdown_callback = s_on_shutdown_complete,
885 .shutdown_user_data = NULL,
886 },
887 };
888
889 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
890
891 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
892
893 s_aws_wait_for_credentials_result();
894
895 ASSERT_SUCCESS(s_verify_credentials(
896 true /*request made*/, false /*from config*/, true /*get creds*/, 1 /*expected attempts*/));
897
898 struct aws_date_time expiration;
899 struct aws_byte_cursor date_cursor = aws_byte_cursor_from_string(s_good_response_expiration);
900 aws_date_time_init_from_str_cursor(&expiration, &date_cursor, AWS_DATE_FORMAT_ISO_8601);
901 ASSERT_INT_EQUALS(
902 aws_credentials_get_expiration_timepoint_seconds(s_tester.credentials), (uint64_t)expiration.timestamp);
903
904 aws_credentials_provider_release(provider);
905
906 s_aws_wait_for_provider_shutdown_callback();
907
908 s_aws_sts_web_identity_tester_cleanup();
909
910 return 0;
911 }
912
913 AWS_TEST_CASE(
914 credentials_provider_sts_web_identity_basic_success_env,
915 s_credentials_provider_sts_web_identity_basic_success_env);
916
s_credentials_provider_sts_web_identity_basic_success_config(struct aws_allocator * allocator,void * ctx)917 static int s_credentials_provider_sts_web_identity_basic_success_config(struct aws_allocator *allocator, void *ctx) {
918 (void)ctx;
919
920 s_aws_sts_web_identity_tester_init(allocator);
921
922 s_aws_sts_web_identity_test_unset_env_parameters();
923
924 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
925 ASSERT_TRUE(token_file_path_str != NULL);
926 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
927
928 struct aws_byte_buf content_buf;
929 struct aws_byte_buf existing_content =
930 aws_byte_buf_from_c_str(aws_string_c_str(s_sts_web_identity_config_file_contents));
931 aws_byte_buf_init_copy(&content_buf, allocator, &existing_content);
932 struct aws_byte_cursor cursor = aws_byte_cursor_from_string(token_file_path_str);
933 ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS);
934 cursor = aws_byte_cursor_from_c_str("\n");
935 ASSERT_TRUE(aws_byte_buf_append_dynamic(&content_buf, &cursor) == AWS_OP_SUCCESS);
936 aws_string_destroy(token_file_path_str);
937
938 struct aws_string *config_file_contents = aws_string_new_from_array(allocator, content_buf.buffer, content_buf.len);
939 ASSERT_TRUE(config_file_contents != NULL);
940 aws_byte_buf_clean_up(&content_buf);
941
942 s_aws_sts_web_identity_test_init_config_profile(allocator, config_file_contents);
943 aws_string_destroy(config_file_contents);
944
945 struct aws_byte_cursor good_response_cursor = aws_byte_cursor_from_string(s_good_response);
946 aws_array_list_push_back(&s_tester.response_data_callbacks, &good_response_cursor);
947
948 struct aws_credentials_provider_sts_web_identity_options options = {
949 .bootstrap = NULL,
950 .tls_ctx = s_tester.tls_ctx,
951 .function_table = &s_mock_function_table,
952 .shutdown_options =
953 {
954 .shutdown_callback = s_on_shutdown_complete,
955 .shutdown_user_data = NULL,
956 },
957 };
958
959 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
960
961 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
962
963 s_aws_wait_for_credentials_result();
964
965 ASSERT_SUCCESS(
966 s_verify_credentials(true /*request made*/, true /*from config*/, true /*get creds*/, 1 /*expected attempts*/));
967
968 struct aws_date_time expiration;
969 struct aws_byte_cursor date_cursor = aws_byte_cursor_from_string(s_good_response_expiration);
970 aws_date_time_init_from_str_cursor(&expiration, &date_cursor, AWS_DATE_FORMAT_ISO_8601);
971 ASSERT_INT_EQUALS(
972 aws_credentials_get_expiration_timepoint_seconds(s_tester.credentials), (uint64_t)expiration.timestamp);
973
974 aws_credentials_provider_release(provider);
975
976 s_aws_wait_for_provider_shutdown_callback();
977
978 s_aws_sts_web_identity_tester_cleanup();
979
980 return 0;
981 }
982
983 AWS_TEST_CASE(
984 credentials_provider_sts_web_identity_basic_success_config,
985 s_credentials_provider_sts_web_identity_basic_success_config);
986
987 AWS_STATIC_STRING_FROM_LITERAL(
988 s_good_response_first_part,
989 "<AssumeRoleWithWebIdentityResponse>"
990 " <AssumeRoleWithWebIdentityResult>"
991 " <AssumedRoleUser>"
992 " <Arn>arn:aws:sts::123456789012:assumed-role/FederatedWebIdentityRole/app1</Arn>"
993 " <AssumedRoleId>AROACLKWSDQRAOEXAMPLE:app1</AssumedRoleId>"
994 " </AssumedRoleUser>"
995 " <Credentials>");
996 AWS_STATIC_STRING_FROM_LITERAL(
997 s_good_response_second_part,
998 " <SessionToken>TokenSuccess</SessionToken>"
999 " <SecretAccessKey>SuccessfulSecret</SecretAccessKey>"
1000 " <Expiration>2020-02-25T06:03:31Z</Expiration>"
1001 " <AccessKeyId>SuccessfulAccessKey</AccessKeyId>"
1002 " </Credentials>"
1003 " <Provider>www.amazon.com</Provider>"
1004 " </AssumeRoleWithWebIdentityResult>"
1005 " <ResponseMetadata>");
1006 AWS_STATIC_STRING_FROM_LITERAL(
1007 s_good_response_third_part,
1008
1009 " <RequestId>ad4156e9-bce1-11e2-82e6-6b6efEXAMPLE</RequestId>"
1010 " </ResponseMetadata>"
1011 "</AssumeRoleWithWebIdentityResponse>");
1012
s_credentials_provider_sts_web_identity_success_multi_part_doc(struct aws_allocator * allocator,void * ctx)1013 static int s_credentials_provider_sts_web_identity_success_multi_part_doc(struct aws_allocator *allocator, void *ctx) {
1014 (void)ctx;
1015
1016 s_aws_sts_web_identity_tester_init(allocator);
1017
1018 s_aws_sts_web_identity_test_unset_env_parameters();
1019
1020 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
1021 ASSERT_TRUE(token_file_path_str != NULL);
1022 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
1023
1024 s_aws_sts_web_identity_test_init_env_parameters(
1025 allocator,
1026 "us-east-1",
1027 "arn:aws:iam::1234567890:role/test-arn",
1028 "9876543210",
1029 aws_string_c_str(token_file_path_str));
1030 aws_string_destroy(token_file_path_str);
1031
1032 struct aws_byte_cursor good_response_cursor1 = aws_byte_cursor_from_string(s_good_response_first_part);
1033 struct aws_byte_cursor good_response_cursor2 = aws_byte_cursor_from_string(s_good_response_second_part);
1034 struct aws_byte_cursor good_response_cursor3 = aws_byte_cursor_from_string(s_good_response_third_part);
1035 aws_array_list_push_back(&s_tester.response_data_callbacks, &good_response_cursor1);
1036 aws_array_list_push_back(&s_tester.response_data_callbacks, &good_response_cursor2);
1037 aws_array_list_push_back(&s_tester.response_data_callbacks, &good_response_cursor3);
1038
1039 struct aws_credentials_provider_sts_web_identity_options options = {
1040 .bootstrap = NULL,
1041 .tls_ctx = s_tester.tls_ctx,
1042 .function_table = &s_mock_function_table,
1043 .shutdown_options =
1044 {
1045 .shutdown_callback = s_on_shutdown_complete,
1046 .shutdown_user_data = NULL,
1047 },
1048 };
1049
1050 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
1051
1052 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
1053
1054 s_aws_wait_for_credentials_result();
1055
1056 ASSERT_SUCCESS(s_verify_credentials(
1057 true /*request made*/, false /*from config*/, true /*get creds*/, 1 /*expected attempts*/));
1058
1059 struct aws_date_time expiration;
1060 struct aws_byte_cursor date_cursor = aws_byte_cursor_from_string(s_good_response_expiration);
1061 aws_date_time_init_from_str_cursor(&expiration, &date_cursor, AWS_DATE_FORMAT_ISO_8601);
1062 ASSERT_INT_EQUALS(
1063 aws_credentials_get_expiration_timepoint_seconds(s_tester.credentials), (uint64_t)expiration.timestamp);
1064
1065 aws_credentials_provider_release(provider);
1066
1067 s_aws_wait_for_provider_shutdown_callback();
1068
1069 s_aws_sts_web_identity_tester_cleanup();
1070
1071 return 0;
1072 }
1073 AWS_TEST_CASE(
1074 credentials_provider_sts_web_identity_success_multi_part_doc,
1075 s_credentials_provider_sts_web_identity_success_multi_part_doc);
1076
s_credentials_provider_sts_web_identity_real_new_destroy(struct aws_allocator * allocator,void * ctx)1077 static int s_credentials_provider_sts_web_identity_real_new_destroy(struct aws_allocator *allocator, void *ctx) {
1078 (void)ctx;
1079
1080 aws_auth_library_init(allocator);
1081
1082 s_aws_sts_web_identity_test_unset_env_parameters();
1083
1084 struct aws_string *token_file_path_str = aws_create_process_unique_file_name(allocator);
1085 ASSERT_TRUE(token_file_path_str != NULL);
1086 ASSERT_TRUE(aws_create_profile_file(token_file_path_str, s_sts_web_identity_token_contents) == AWS_OP_SUCCESS);
1087
1088 s_aws_sts_web_identity_test_init_env_parameters(
1089 allocator,
1090 "us-east-1",
1091 "arn:aws:iam::1234567890:role/test-arn",
1092 "9876543210",
1093 aws_string_c_str(token_file_path_str));
1094 aws_string_destroy(token_file_path_str);
1095
1096 s_aws_sts_web_identity_tester_init(allocator);
1097
1098 struct aws_event_loop_group *el_group = aws_event_loop_group_new_default(allocator, 1, NULL);
1099
1100 struct aws_host_resolver_default_options resolver_options = {
1101 .el_group = el_group,
1102 .max_entries = 8,
1103 };
1104 struct aws_host_resolver *resolver = aws_host_resolver_new_default(allocator, &resolver_options);
1105
1106 struct aws_client_bootstrap_options bootstrap_options = {
1107 .event_loop_group = el_group,
1108 .host_resolver = resolver,
1109 };
1110 struct aws_client_bootstrap *bootstrap = aws_client_bootstrap_new(allocator, &bootstrap_options);
1111
1112 struct aws_credentials_provider_sts_web_identity_options options = {
1113 .bootstrap = bootstrap,
1114 .tls_ctx = s_tester.tls_ctx,
1115 .shutdown_options =
1116 {
1117 .shutdown_callback = s_on_shutdown_complete,
1118 .shutdown_user_data = NULL,
1119 },
1120 };
1121
1122 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
1123
1124 aws_credentials_provider_get_credentials(provider, s_get_credentials_callback, NULL);
1125
1126 s_aws_wait_for_credentials_result();
1127
1128 aws_credentials_provider_release(provider);
1129
1130 s_aws_wait_for_provider_shutdown_callback();
1131
1132 aws_client_bootstrap_release(bootstrap);
1133 aws_host_resolver_release(resolver);
1134 aws_event_loop_group_release(el_group);
1135
1136 s_aws_sts_web_identity_tester_cleanup();
1137
1138 aws_auth_library_clean_up();
1139
1140 return 0;
1141 }
1142 AWS_TEST_CASE(
1143 credentials_provider_sts_web_identity_real_new_destroy,
1144 s_credentials_provider_sts_web_identity_real_new_destroy);
1145