1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include "credentials.h"
7 #include "crt.h"
8 #include "http_connection_manager.h"
9 #include "java_class_ids.h"
10
11 #include <http_proxy_options.h>
12 #include <jni.h>
13 #include <string.h>
14
15 #include <aws/auth/credentials.h>
16 #include <aws/common/clock.h>
17 #include <aws/common/string.h>
18 #include <aws/http/connection.h>
19 #include <aws/http/proxy.h>
20 #include <aws/io/tls_channel_handler.h>
21
22 /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */
23 #if UINTPTR_MAX == 0xffffffff
24 # if defined(_MSC_VER)
25 # pragma warning(push)
26 # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */
27 # else
28 # pragma GCC diagnostic push
29 # pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
30 # pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
31 # endif
32 #endif
33
34 struct aws_credentials_provider_callback_data {
35 JavaVM *jvm;
36 struct aws_credentials_provider *provider;
37 jweak java_crt_credentials_provider;
38
39 jobject jni_delegate_credential_handler;
40 };
41
s_callback_data_clean_up(JNIEnv * env,struct aws_allocator * allocator,struct aws_credentials_provider_callback_data * callback_data)42 static void s_callback_data_clean_up(
43 JNIEnv *env,
44 struct aws_allocator *allocator,
45 struct aws_credentials_provider_callback_data *callback_data) {
46
47 (*env)->DeleteWeakGlobalRef(env, callback_data->java_crt_credentials_provider);
48 if (callback_data->jni_delegate_credential_handler != NULL) {
49 (*env)->DeleteGlobalRef(env, callback_data->jni_delegate_credential_handler);
50 }
51
52 aws_mem_release(allocator, callback_data);
53 }
54
s_on_shutdown_complete(void * user_data)55 static void s_on_shutdown_complete(void *user_data) {
56 struct aws_credentials_provider_callback_data *callback_data = user_data;
57
58 AWS_LOGF_DEBUG(AWS_LS_AUTH_CREDENTIALS_PROVIDER, "Credentials providers shutdown complete");
59
60 // Tell the Java credentials providers that shutdown is done. This lets it release its references.
61 /********** JNI ENV ACQUIRE **********/
62 JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
63 if (env == NULL) {
64 /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
65 return;
66 }
67
68 jobject java_crt_credentials_provider = (*env)->NewLocalRef(env, callback_data->java_crt_credentials_provider);
69 if (java_crt_credentials_provider != NULL) {
70 (*env)->CallVoidMethod(
71 env, java_crt_credentials_provider, credentials_provider_properties.on_shutdown_complete_method_id);
72
73 (*env)->DeleteLocalRef(env, java_crt_credentials_provider);
74 AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env));
75 }
76
77 struct aws_allocator *allocator = aws_jni_get_allocator();
78 // We're done with this callback data, clean it up.
79
80 JavaVM *jvm = callback_data->jvm;
81 s_callback_data_clean_up(env, allocator, callback_data);
82
83 aws_jni_release_thread_env(jvm, env);
84 /********** JNI ENV RELEASE **********/
85 }
86
87 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_StaticCredentialsProvider_staticCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jbyteArray access_key_id,jbyteArray secret_access_key,jbyteArray session_token)88 Java_software_amazon_awssdk_crt_auth_credentials_StaticCredentialsProvider_staticCredentialsProviderNew(
89 JNIEnv *env,
90 jclass jni_class,
91 jobject java_crt_credentials_provider,
92 jbyteArray access_key_id,
93 jbyteArray secret_access_key,
94 jbyteArray session_token) {
95
96 (void)jni_class;
97 aws_cache_jni_ids(env);
98
99 struct aws_allocator *allocator = aws_jni_get_allocator();
100
101 struct aws_credentials_provider_callback_data *callback_data =
102 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
103 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
104
105 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
106 AWS_FATAL_ASSERT(jvmresult == 0);
107
108 struct aws_credentials_provider_static_options options;
109 AWS_ZERO_STRUCT(options);
110 options.access_key_id = aws_jni_byte_cursor_from_jbyteArray_acquire(env, access_key_id);
111 options.secret_access_key = aws_jni_byte_cursor_from_jbyteArray_acquire(env, secret_access_key);
112 if (session_token) {
113 options.session_token = aws_jni_byte_cursor_from_jbyteArray_acquire(env, session_token);
114 }
115 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
116 options.shutdown_options.shutdown_user_data = callback_data;
117
118 struct aws_credentials_provider *provider = aws_credentials_provider_new_static(allocator, &options);
119 if (provider == NULL) {
120 s_callback_data_clean_up(env, allocator, callback_data);
121 aws_jni_throw_runtime_exception(env, "Failed to create static credentials provider");
122 } else {
123 callback_data->provider = provider;
124 }
125
126 aws_jni_byte_cursor_from_jbyteArray_release(env, access_key_id, options.access_key_id);
127 aws_jni_byte_cursor_from_jbyteArray_release(env, secret_access_key, options.secret_access_key);
128
129 if (session_token) {
130 aws_jni_byte_cursor_from_jbyteArray_release(env, session_token, options.session_token);
131 }
132
133 return (jlong)provider;
134 }
135
136 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_DefaultChainCredentialsProvider_defaultChainCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrapHandle)137 Java_software_amazon_awssdk_crt_auth_credentials_DefaultChainCredentialsProvider_defaultChainCredentialsProviderNew(
138 JNIEnv *env,
139 jclass jni_class,
140 jobject java_crt_credentials_provider,
141 jlong bootstrapHandle) {
142
143 (void)jni_class;
144 (void)env;
145 aws_cache_jni_ids(env);
146
147 struct aws_allocator *allocator = aws_jni_get_allocator();
148 struct aws_credentials_provider_callback_data *callback_data =
149 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
150 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
151
152 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
153 AWS_FATAL_ASSERT(jvmresult == 0);
154
155 struct aws_credentials_provider_chain_default_options options;
156 AWS_ZERO_STRUCT(options);
157 options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle;
158 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
159 options.shutdown_options.shutdown_user_data = callback_data;
160
161 struct aws_credentials_provider *provider = aws_credentials_provider_new_chain_default(allocator, &options);
162 if (provider == NULL) {
163 s_callback_data_clean_up(env, allocator, callback_data);
164 aws_jni_throw_runtime_exception(env, "Failed to create default credentials provider chain");
165 } else {
166 callback_data->provider = provider;
167 }
168
169 return (jlong)provider;
170 }
171
172 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_ProfileCredentialsProvider_profileCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrapHandle,jlong tls_context_handle,jbyteArray profile_name_override,jbyteArray config_file_name_override,jbyteArray credentials_file_name_override)173 Java_software_amazon_awssdk_crt_auth_credentials_ProfileCredentialsProvider_profileCredentialsProviderNew(
174 JNIEnv *env,
175 jclass jni_class,
176 jobject java_crt_credentials_provider,
177 jlong bootstrapHandle,
178 jlong tls_context_handle,
179 jbyteArray profile_name_override,
180 jbyteArray config_file_name_override,
181 jbyteArray credentials_file_name_override) {
182
183 (void)jni_class;
184 (void)env;
185 aws_cache_jni_ids(env);
186
187 struct aws_allocator *allocator = aws_jni_get_allocator();
188 struct aws_credentials_provider_callback_data *callback_data =
189 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
190 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
191
192 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
193 AWS_FATAL_ASSERT(jvmresult == 0);
194
195 struct aws_credentials_provider_profile_options options;
196 AWS_ZERO_STRUCT(options);
197 options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle;
198 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
199 options.shutdown_options.shutdown_user_data = callback_data;
200 options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle;
201
202 if (profile_name_override) {
203 options.profile_name_override = aws_jni_byte_cursor_from_jbyteArray_acquire(env, profile_name_override);
204 }
205
206 if (config_file_name_override) {
207 options.config_file_name_override = aws_jni_byte_cursor_from_jbyteArray_acquire(env, config_file_name_override);
208 }
209
210 if (credentials_file_name_override) {
211 options.credentials_file_name_override =
212 aws_jni_byte_cursor_from_jbyteArray_acquire(env, credentials_file_name_override);
213 }
214
215 struct aws_credentials_provider *provider = aws_credentials_provider_new_profile(allocator, &options);
216 if (provider == NULL) {
217 s_callback_data_clean_up(env, allocator, callback_data);
218 aws_jni_throw_runtime_exception(env, "Failed to create profile credentials provider");
219 } else {
220 callback_data->provider = provider;
221 }
222
223 if (profile_name_override) {
224 aws_jni_byte_cursor_from_jbyteArray_release(env, profile_name_override, options.profile_name_override);
225 }
226
227 if (config_file_name_override) {
228 aws_jni_byte_cursor_from_jbyteArray_release(env, config_file_name_override, options.config_file_name_override);
229 }
230
231 if (credentials_file_name_override) {
232 aws_jni_byte_cursor_from_jbyteArray_release(
233 env, credentials_file_name_override, options.credentials_file_name_override);
234 }
235
236 return (jlong)provider;
237 }
238
239 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_EcsCredentialsProvider_ecsCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrapHandle,jlong tls_context_handle,jbyteArray host,jbyteArray path_and_query,jbyteArray auth_token)240 Java_software_amazon_awssdk_crt_auth_credentials_EcsCredentialsProvider_ecsCredentialsProviderNew(
241 JNIEnv *env,
242 jclass jni_class,
243 jobject java_crt_credentials_provider,
244 jlong bootstrapHandle,
245 jlong tls_context_handle,
246 jbyteArray host,
247 jbyteArray path_and_query,
248 jbyteArray auth_token) {
249
250 (void)jni_class;
251 (void)env;
252 aws_cache_jni_ids(env);
253
254 struct aws_allocator *allocator = aws_jni_get_allocator();
255 struct aws_credentials_provider_callback_data *callback_data =
256 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
257 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
258
259 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
260 AWS_FATAL_ASSERT(jvmresult == 0);
261
262 struct aws_credentials_provider_ecs_options options;
263 AWS_ZERO_STRUCT(options);
264 options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle;
265 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
266 options.shutdown_options.shutdown_user_data = callback_data;
267 options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle;
268
269 if (host) {
270 options.host = aws_jni_byte_cursor_from_jbyteArray_acquire(env, host);
271 }
272
273 if (path_and_query) {
274 options.path_and_query = aws_jni_byte_cursor_from_jbyteArray_acquire(env, path_and_query);
275 }
276
277 if (auth_token) {
278 options.auth_token = aws_jni_byte_cursor_from_jbyteArray_acquire(env, auth_token);
279 }
280
281 struct aws_credentials_provider *provider = aws_credentials_provider_new_ecs(allocator, &options);
282 if (provider == NULL) {
283 s_callback_data_clean_up(env, allocator, callback_data);
284 aws_jni_throw_runtime_exception(env, "Failed to create ECS credentials provider");
285 } else {
286 callback_data->provider = provider;
287 }
288
289 if (host) {
290 aws_jni_byte_cursor_from_jbyteArray_release(env, host, options.host);
291 }
292
293 if (path_and_query) {
294 aws_jni_byte_cursor_from_jbyteArray_release(env, path_and_query, options.path_and_query);
295 }
296
297 if (auth_token) {
298 aws_jni_byte_cursor_from_jbyteArray_release(env, auth_token, options.auth_token);
299 }
300
301 return (jlong)provider;
302 }
303
304 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_StsCredentialsProvider_stsCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrapHandle,jlong tls_context_handle,jlong creds_provider,jbyteArray role_arn,jbyteArray session_name,jlong duration_seconds)305 Java_software_amazon_awssdk_crt_auth_credentials_StsCredentialsProvider_stsCredentialsProviderNew(
306 JNIEnv *env,
307 jclass jni_class,
308 jobject java_crt_credentials_provider,
309 jlong bootstrapHandle,
310 jlong tls_context_handle,
311 jlong creds_provider,
312 jbyteArray role_arn,
313 jbyteArray session_name,
314 jlong duration_seconds) {
315
316 (void)jni_class;
317 (void)env;
318 aws_cache_jni_ids(env);
319
320 struct aws_allocator *allocator = aws_jni_get_allocator();
321 struct aws_credentials_provider_callback_data *callback_data =
322 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
323 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
324
325 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
326 AWS_FATAL_ASSERT(jvmresult == 0);
327
328 struct aws_credentials_provider_sts_options options;
329 AWS_ZERO_STRUCT(options);
330 options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle;
331 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
332 options.shutdown_options.shutdown_user_data = callback_data;
333 options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle;
334
335 options.creds_provider = (struct aws_credentials_provider *)creds_provider;
336
337 if (role_arn) {
338 options.role_arn = aws_jni_byte_cursor_from_jbyteArray_acquire(env, role_arn);
339 }
340
341 if (session_name) {
342 options.session_name = aws_jni_byte_cursor_from_jbyteArray_acquire(env, session_name);
343 }
344
345 options.duration_seconds =
346 (uint16_t)aws_timestamp_convert(duration_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_SECS, NULL);
347
348 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts(allocator, &options);
349 if (provider == NULL) {
350 s_callback_data_clean_up(env, allocator, callback_data);
351 aws_jni_throw_runtime_exception(env, "Failed to create STS credentials provider");
352 } else {
353 callback_data->provider = provider;
354 }
355
356 if (role_arn) {
357 aws_jni_byte_cursor_from_jbyteArray_release(env, role_arn, options.role_arn);
358 }
359
360 if (session_name) {
361 aws_jni_byte_cursor_from_jbyteArray_release(env, session_name, options.session_name);
362 }
363
364 return (jlong)provider;
365 }
366
367 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_StsWebIdentityCredentialsProvider_stsWebIdentityCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrapHandle,jlong tls_context_handle)368 Java_software_amazon_awssdk_crt_auth_credentials_StsWebIdentityCredentialsProvider_stsWebIdentityCredentialsProviderNew(
369 JNIEnv *env,
370 jclass jni_class,
371 jobject java_crt_credentials_provider,
372 jlong bootstrapHandle,
373 jlong tls_context_handle) {
374
375 (void)jni_class;
376 (void)env;
377 aws_cache_jni_ids(env);
378
379 struct aws_allocator *allocator = aws_jni_get_allocator();
380 struct aws_credentials_provider_callback_data *callback_data =
381 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
382 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
383
384 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
385 AWS_FATAL_ASSERT(jvmresult == 0);
386
387 struct aws_credentials_provider_sts_web_identity_options options;
388 AWS_ZERO_STRUCT(options);
389 options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle;
390 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
391 options.shutdown_options.shutdown_user_data = callback_data;
392 options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle;
393
394 struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options);
395 if (provider == NULL) {
396 s_callback_data_clean_up(env, allocator, callback_data);
397 aws_jni_throw_runtime_exception(env, "Failed to create STS web identity credentials provider");
398 } else {
399 callback_data->provider = provider;
400 }
401
402 return (jlong)provider;
403 }
404
405 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_X509CredentialsProvider_x509CredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jlong bootstrap_handle,jlong tls_context_handle,jbyteArray thing_name,jbyteArray role_alias,jbyteArray endpoint,jint proxy_connection_type,jbyteArray jni_proxy_host,jint jni_proxy_port,jlong jni_proxy_tls_context,jint jni_proxy_authorization_type,jbyteArray jni_proxy_authorization_username,jbyteArray jni_proxy_authorization_password)406 Java_software_amazon_awssdk_crt_auth_credentials_X509CredentialsProvider_x509CredentialsProviderNew(
407 JNIEnv *env,
408 jclass jni_class,
409 jobject java_crt_credentials_provider,
410 jlong bootstrap_handle,
411 jlong tls_context_handle,
412 jbyteArray thing_name,
413 jbyteArray role_alias,
414 jbyteArray endpoint,
415 jint proxy_connection_type,
416 jbyteArray jni_proxy_host,
417 jint jni_proxy_port,
418 jlong jni_proxy_tls_context,
419 jint jni_proxy_authorization_type,
420 jbyteArray jni_proxy_authorization_username,
421 jbyteArray jni_proxy_authorization_password) {
422
423 (void)jni_class;
424 (void)env;
425 aws_cache_jni_ids(env);
426
427 struct aws_allocator *allocator = aws_jni_get_allocator();
428 struct aws_credentials_provider_callback_data *callback_data =
429 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
430 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
431
432 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
433 AWS_FATAL_ASSERT(jvmresult == 0);
434
435 struct aws_tls_connection_options tls_connection_options;
436 AWS_ZERO_STRUCT(tls_connection_options);
437 aws_tls_connection_options_init_from_ctx(&tls_connection_options, (struct aws_tls_ctx *)tls_context_handle);
438
439 struct aws_credentials_provider_x509_options options;
440 AWS_ZERO_STRUCT(options);
441 options.bootstrap = (struct aws_client_bootstrap *)bootstrap_handle;
442 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
443 options.shutdown_options.shutdown_user_data = callback_data;
444 options.tls_connection_options = &tls_connection_options;
445 options.thing_name = aws_jni_byte_cursor_from_jbyteArray_acquire(env, thing_name);
446 options.role_alias = aws_jni_byte_cursor_from_jbyteArray_acquire(env, role_alias);
447 options.endpoint = aws_jni_byte_cursor_from_jbyteArray_acquire(env, endpoint);
448
449 struct aws_tls_connection_options proxy_tls_connection_options;
450 AWS_ZERO_STRUCT(proxy_tls_connection_options);
451 struct aws_http_proxy_options proxy_options;
452 AWS_ZERO_STRUCT(proxy_options);
453
454 aws_http_proxy_options_jni_init(
455 env,
456 &proxy_options,
457 proxy_connection_type,
458 &proxy_tls_connection_options,
459 jni_proxy_host,
460 jni_proxy_port,
461 jni_proxy_authorization_username,
462 jni_proxy_authorization_password,
463 jni_proxy_authorization_type,
464 (struct aws_tls_ctx *)jni_proxy_tls_context);
465
466 if (jni_proxy_host != NULL) {
467 options.proxy_options = &proxy_options;
468 }
469
470 struct aws_credentials_provider *provider = aws_credentials_provider_new_x509(allocator, &options);
471 if (provider == NULL) {
472 s_callback_data_clean_up(env, allocator, callback_data);
473 aws_jni_throw_runtime_exception(env, "Failed to create X509 credentials provider");
474 } else {
475 callback_data->provider = provider;
476 }
477
478 aws_jni_byte_cursor_from_jbyteArray_release(env, thing_name, options.thing_name);
479 aws_jni_byte_cursor_from_jbyteArray_release(env, role_alias, options.role_alias);
480 aws_jni_byte_cursor_from_jbyteArray_release(env, endpoint, options.endpoint);
481
482 aws_http_proxy_options_jni_clean_up(
483 env, &proxy_options, jni_proxy_host, jni_proxy_authorization_username, jni_proxy_authorization_password);
484
485 aws_tls_connection_options_clean_up(&tls_connection_options);
486
487 return (jlong)provider;
488 }
489
490 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_CachedCredentialsProvider_cachedCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jint cached_duration_in_seconds,jlong native_cached_provider)491 Java_software_amazon_awssdk_crt_auth_credentials_CachedCredentialsProvider_cachedCredentialsProviderNew(
492 JNIEnv *env,
493 jclass jni_class,
494 jobject java_crt_credentials_provider,
495 jint cached_duration_in_seconds,
496 jlong native_cached_provider) {
497
498 (void)jni_class;
499 aws_cache_jni_ids(env);
500
501 if (native_cached_provider == 0) {
502 aws_jni_throw_runtime_exception(
503 env, "CachedCredentialsProviderials.cachedCredentialsProviderNew: cached provider is null");
504 return 0;
505 }
506
507 struct aws_allocator *allocator = aws_jni_get_allocator();
508
509 struct aws_credentials_provider_callback_data *callback_data =
510 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
511 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
512
513 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
514 AWS_FATAL_ASSERT(jvmresult == 0);
515
516 struct aws_credentials_provider_cached_options options;
517 AWS_ZERO_STRUCT(options);
518 options.refresh_time_in_milliseconds =
519 aws_timestamp_convert(cached_duration_in_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_MILLIS, NULL);
520 options.source = (struct aws_credentials_provider *)native_cached_provider;
521
522 options.shutdown_options.shutdown_callback = s_on_shutdown_complete;
523 options.shutdown_options.shutdown_user_data = callback_data;
524
525 struct aws_credentials_provider *provider = aws_credentials_provider_new_cached(allocator, &options);
526 if (provider == NULL) {
527 s_callback_data_clean_up(env, allocator, callback_data);
528 aws_jni_throw_runtime_exception(env, "Failed to create cached credentials provider");
529 } else {
530 callback_data->provider = provider;
531 }
532
533 return (jlong)provider;
534 }
535
s_credentials_provider_delegate_get_credentials(void * delegate_user_data,aws_on_get_credentials_callback_fn callback,void * callback_user_data)536 static int s_credentials_provider_delegate_get_credentials(
537 void *delegate_user_data,
538 aws_on_get_credentials_callback_fn callback,
539 void *callback_user_data) {
540
541 struct aws_credentials_provider_callback_data *callback_data = delegate_user_data;
542
543 int return_value = AWS_OP_ERR;
544
545 /********** JNI ENV ACQUIRE **********/
546 JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
547 if (env == NULL) {
548 /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
549 return AWS_OP_ERR;
550 }
551
552 // Fetch credentials from java
553 jobject java_credentials = (*env)->CallObjectMethod(
554 env,
555 callback_data->jni_delegate_credential_handler,
556 credentials_handler_properties.on_handler_get_credentials_method_id);
557 if (aws_jni_check_and_clear_exception(env)) {
558 aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
559 goto done;
560 }
561
562 struct aws_credentials *native_credentials = aws_credentials_new_from_java_credentials(env, java_credentials);
563 if (!native_credentials) {
564 aws_jni_throw_runtime_exception(env, "Failed to create native credentials");
565 // error has been raised from creating function
566 goto done;
567 }
568 callback(native_credentials, AWS_ERROR_SUCCESS, callback_user_data);
569 aws_credentials_release(native_credentials);
570
571 return_value = AWS_OP_SUCCESS;
572
573 done:
574 (*env)->DeleteLocalRef(env, java_credentials);
575
576 aws_jni_release_thread_env(callback_data->jvm, env);
577 /********** JNI ENV RELEASE **********/
578
579 return return_value;
580 }
581
582 JNIEXPORT jlong JNICALL
Java_software_amazon_awssdk_crt_auth_credentials_DelegateCredentialsProvider_delegateCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject java_crt_credentials_provider,jobject jni_delegate_credential_handler)583 Java_software_amazon_awssdk_crt_auth_credentials_DelegateCredentialsProvider_delegateCredentialsProviderNew(
584 JNIEnv *env,
585 jclass jni_class,
586 jobject java_crt_credentials_provider,
587 jobject jni_delegate_credential_handler) {
588
589 (void)jni_class;
590 (void)env;
591 aws_cache_jni_ids(env);
592
593 struct aws_allocator *allocator = aws_jni_get_allocator();
594 struct aws_credentials_provider_callback_data *callback_data =
595 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
596 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider);
597 callback_data->jni_delegate_credential_handler = (*env)->NewGlobalRef(env, jni_delegate_credential_handler);
598
599 struct aws_credentials_provider_delegate_options options = {
600 .get_credentials = s_credentials_provider_delegate_get_credentials,
601 .delegate_user_data = callback_data,
602 .shutdown_options =
603 {
604 .shutdown_callback = s_on_shutdown_complete,
605 .shutdown_user_data = callback_data,
606 },
607 };
608
609 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
610 AWS_FATAL_ASSERT(jvmresult == 0);
611
612 struct aws_credentials_provider *provider = aws_credentials_provider_new_delegate(allocator, &options);
613 if (provider == NULL) {
614 s_callback_data_clean_up(env, allocator, callback_data);
615 aws_jni_throw_runtime_exception(env, "Failed to create delegate credentials provider");
616 } else {
617 callback_data->provider = provider;
618 }
619
620 return (jlong)provider;
621 }
622
s_fill_in_logins(struct aws_array_list * logins,struct aws_byte_cursor marshalled_logins)623 static int s_fill_in_logins(struct aws_array_list *logins, struct aws_byte_cursor marshalled_logins) {
624 struct aws_byte_cursor logins_cursor = marshalled_logins;
625 uint32_t field_len = 0;
626
627 while (logins_cursor.len > 0) {
628 if (!aws_byte_cursor_read_be32(&logins_cursor, &field_len)) {
629 return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
630 }
631
632 struct aws_byte_cursor identity_provider_name = aws_byte_cursor_advance(&logins_cursor, field_len);
633
634 if (!aws_byte_cursor_read_be32(&logins_cursor, &field_len)) {
635 return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
636 }
637
638 struct aws_byte_cursor identity_provider_token = aws_byte_cursor_advance(&logins_cursor, field_len);
639
640 struct aws_cognito_identity_provider_token_pair login_pair = {
641 .identity_provider_name = identity_provider_name,
642 .identity_provider_token = identity_provider_token,
643 };
644
645 aws_array_list_push_back(logins, &login_pair);
646 }
647
648 return AWS_OP_SUCCESS;
649 }
650
651 JNIEXPORT
Java_software_amazon_awssdk_crt_auth_credentials_CognitoCredentialsProvider_cognitoCredentialsProviderNew(JNIEnv * env,jclass jni_class,jobject crt_credentials_provider,jlong native_bootstrap,jlong native_tls_context,jstring endpoint,jstring identity,jstring custom_role_arn,jbyteArray marshalled_logins,jint proxy_connection_type,jbyteArray proxy_host,jint proxy_port,jlong native_proxy_tls_context,jint proxy_authorization_type,jbyteArray proxy_authorization_username,jbyteArray proxy_authorization_password)652 jlong JNICALL Java_software_amazon_awssdk_crt_auth_credentials_CognitoCredentialsProvider_cognitoCredentialsProviderNew(
653 JNIEnv *env,
654 jclass jni_class,
655 jobject crt_credentials_provider,
656 jlong native_bootstrap,
657 jlong native_tls_context,
658 jstring endpoint,
659 jstring identity,
660 jstring custom_role_arn,
661 jbyteArray marshalled_logins,
662 jint proxy_connection_type,
663 jbyteArray proxy_host,
664 jint proxy_port,
665 jlong native_proxy_tls_context,
666 jint proxy_authorization_type,
667 jbyteArray proxy_authorization_username,
668 jbyteArray proxy_authorization_password) {
669
670 (void)jni_class;
671 (void)env;
672 aws_cache_jni_ids(env);
673
674 struct aws_allocator *allocator = aws_jni_get_allocator();
675 struct aws_credentials_provider *provider = NULL;
676 struct aws_credentials_provider_callback_data *callback_data = NULL;
677
678 struct aws_tls_connection_options proxy_tls_connection_options;
679 AWS_ZERO_STRUCT(proxy_tls_connection_options);
680 struct aws_http_proxy_options proxy_options;
681 AWS_ZERO_STRUCT(proxy_options);
682
683 struct aws_byte_cursor endpoint_cursor;
684 AWS_ZERO_STRUCT(endpoint_cursor);
685 struct aws_byte_cursor identity_cursor;
686 AWS_ZERO_STRUCT(identity_cursor);
687 struct aws_byte_cursor custom_role_arn_cursor;
688 AWS_ZERO_STRUCT(custom_role_arn_cursor);
689 struct aws_byte_cursor logins_cursor;
690 AWS_ZERO_STRUCT(logins_cursor);
691
692 struct aws_array_list logins;
693 aws_array_list_init_dynamic(&logins, allocator, 0, sizeof(struct aws_cognito_identity_provider_token_pair));
694
695 if (endpoint == NULL || identity == NULL) {
696 goto done;
697 }
698
699 endpoint_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, endpoint);
700 identity_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, identity);
701
702 callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data));
703
704 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
705 AWS_FATAL_ASSERT(jvmresult == 0);
706 callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, crt_credentials_provider);
707
708 struct aws_credentials_provider_cognito_options options = {
709 .shutdown_options =
710 {
711 .shutdown_callback = s_on_shutdown_complete,
712 .shutdown_user_data = callback_data,
713 },
714 .endpoint = endpoint_cursor,
715 .identity = identity_cursor,
716 .bootstrap = (void *)native_bootstrap,
717 .tls_ctx = (void *)native_tls_context,
718 };
719
720 if (custom_role_arn != NULL) {
721 custom_role_arn_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, custom_role_arn);
722 options.custom_role_arn = &custom_role_arn_cursor;
723 }
724
725 if (marshalled_logins != NULL) {
726 logins_cursor = aws_jni_byte_cursor_from_jbyteArray_acquire(env, marshalled_logins);
727 if (s_fill_in_logins(&logins, logins_cursor)) {
728 goto done;
729 }
730
731 options.logins = logins.data;
732 options.login_count = aws_array_list_length(&logins);
733 }
734
735 if (proxy_host != NULL) {
736 aws_http_proxy_options_jni_init(
737 env,
738 &proxy_options,
739 proxy_connection_type,
740 &proxy_tls_connection_options,
741 proxy_host,
742 proxy_port,
743 proxy_authorization_username,
744 proxy_authorization_password,
745 proxy_authorization_type,
746 (struct aws_tls_ctx *)native_proxy_tls_context);
747
748 options.http_proxy_options = &proxy_options;
749 }
750
751 provider = aws_credentials_provider_new_cognito(allocator, &options);
752 if (provider != NULL) {
753 callback_data->provider = provider;
754 }
755
756 done:
757
758 aws_jni_byte_cursor_from_jstring_release(env, endpoint, endpoint_cursor);
759 aws_jni_byte_cursor_from_jstring_release(env, identity, identity_cursor);
760 aws_jni_byte_cursor_from_jstring_release(env, custom_role_arn, custom_role_arn_cursor);
761 aws_jni_byte_cursor_from_jbyteArray_release(env, marshalled_logins, logins_cursor);
762
763 aws_http_proxy_options_jni_clean_up(
764 env, &proxy_options, proxy_host, proxy_authorization_username, proxy_authorization_password);
765
766 aws_array_list_clean_up(&logins);
767
768 if (provider == NULL) {
769 s_callback_data_clean_up(env, allocator, callback_data);
770 aws_jni_throw_runtime_exception(env, "Failed to create native cognito credentials provider");
771 }
772
773 return (jlong)provider;
774 }
775
776 JNIEXPORT
Java_software_amazon_awssdk_crt_auth_credentials_CredentialsProvider_credentialsProviderDestroy(JNIEnv * env,jclass jni_cp,jobject cp_object,jlong cp_addr)777 void JNICALL Java_software_amazon_awssdk_crt_auth_credentials_CredentialsProvider_credentialsProviderDestroy(
778 JNIEnv *env,
779 jclass jni_cp,
780 jobject cp_object,
781 jlong cp_addr) {
782 (void)jni_cp;
783 (void)cp_object;
784 aws_cache_jni_ids(env);
785
786 struct aws_credentials_provider *provider = (struct aws_credentials_provider *)cp_addr;
787 if (!provider) {
788 aws_jni_throw_runtime_exception(
789 env, "CredentialsProvider.credentialsProviderDestroy: instance should be non-null at destruction time");
790 return;
791 }
792
793 aws_credentials_provider_release(provider);
794 }
795
796 struct aws_credentials_provider_get_credentials_callback_data {
797 JavaVM *jvm;
798 struct aws_credentials_provider *provider;
799 jobject java_crt_credentials_provider;
800 jobject java_credentials_future;
801 };
802
s_cp_callback_data_clean_up(struct aws_credentials_provider_get_credentials_callback_data * callback_data,JNIEnv * env)803 static void s_cp_callback_data_clean_up(
804 struct aws_credentials_provider_get_credentials_callback_data *callback_data,
805 JNIEnv *env) {
806 if (callback_data == NULL || env == NULL) {
807 return;
808 }
809
810 (*env)->DeleteGlobalRef(env, callback_data->java_crt_credentials_provider);
811 (*env)->DeleteGlobalRef(env, callback_data->java_credentials_future);
812
813 aws_credentials_provider_release(callback_data->provider);
814
815 // We're done with this callback data, free it.
816 aws_mem_release(aws_jni_get_allocator(), callback_data);
817 }
818
s_on_get_credentials_callback(struct aws_credentials * credentials,int error_code,void * user_data)819 static void s_on_get_credentials_callback(struct aws_credentials *credentials, int error_code, void *user_data) {
820 (void)error_code;
821
822 struct aws_credentials_provider_get_credentials_callback_data *callback_data = user_data;
823
824 /********** JNI ENV ACQUIRE **********/
825 JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
826 if (env == NULL) {
827 /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
828 return;
829 }
830
831 jobject java_credentials = NULL;
832
833 if (credentials) {
834 java_credentials = aws_java_credentials_from_native_new(env, credentials);
835 }
836
837 (*env)->CallVoidMethod(
838 env,
839 callback_data->java_crt_credentials_provider,
840 credentials_provider_properties.on_get_credentials_complete_method_id,
841 callback_data->java_credentials_future,
842 java_credentials);
843
844 AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env));
845
846 if (java_credentials != NULL) {
847 (*env)->DeleteLocalRef(env, java_credentials);
848 }
849
850 JavaVM *jvm = callback_data->jvm;
851 s_cp_callback_data_clean_up(callback_data, env);
852
853 aws_jni_release_thread_env(jvm, env);
854 /********** JNI ENV RELEASE **********/
855 }
856
857 JNIEXPORT
Java_software_amazon_awssdk_crt_auth_credentials_CredentialsProvider_credentialsProviderGetCredentials(JNIEnv * env,jclass jni_cp,jobject java_crt_credentials_provider,jobject java_credentials_future,jlong native_credentials_provider)858 void JNICALL Java_software_amazon_awssdk_crt_auth_credentials_CredentialsProvider_credentialsProviderGetCredentials(
859 JNIEnv *env,
860 jclass jni_cp,
861 jobject java_crt_credentials_provider,
862 jobject java_credentials_future,
863 jlong native_credentials_provider) {
864 (void)jni_cp;
865 aws_cache_jni_ids(env);
866
867 struct aws_credentials_provider *provider = (struct aws_credentials_provider *)native_credentials_provider;
868 if (!provider) {
869 aws_jni_throw_runtime_exception(
870 env, "CredentialsProvider.credentialsProviderGetCredentials: instance should be non-null");
871 return;
872 }
873
874 if (java_crt_credentials_provider == NULL || java_credentials_future == NULL) {
875 aws_jni_throw_runtime_exception(
876 env, "CredentialsProvider.credentialsProviderGetCredentials: called with null parameters");
877 return;
878 }
879
880 struct aws_allocator *allocator = aws_jni_get_allocator();
881 struct aws_credentials_provider_get_credentials_callback_data *callback_data =
882 aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_get_credentials_callback_data));
883 callback_data->java_crt_credentials_provider = (*env)->NewGlobalRef(env, java_crt_credentials_provider);
884 callback_data->java_credentials_future = (*env)->NewGlobalRef(env, java_credentials_future);
885 callback_data->provider = provider;
886
887 jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
888 AWS_FATAL_ASSERT(jvmresult == 0);
889
890 aws_credentials_provider_acquire(provider);
891
892 if (aws_credentials_provider_get_credentials(provider, s_on_get_credentials_callback, callback_data)) {
893 aws_jni_throw_runtime_exception(env, "CrtCredentialsProvider.credentialsProviderGetCredentials: call failure");
894 /* callback will not be invoked on failure, clean up the resource here. */
895 s_cp_callback_data_clean_up(callback_data, env);
896 }
897 }
898
899 #if UINTPTR_MAX == 0xffffffff
900 # if defined(_MSC_VER)
901 # pragma warning(pop)
902 # else
903 # pragma GCC diagnostic pop
904 # endif
905 #endif
906