/** * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0. */ #include "credentials.h" #include "crt.h" #include "http_connection_manager.h" #include "java_class_ids.h" #include #include #include #include #include #include #include #include #include /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */ #if UINTPTR_MAX == 0xffffffff # if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */ # else # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wpointer-to-int-cast" # pragma GCC diagnostic ignored "-Wint-to-pointer-cast" # endif #endif struct aws_credentials_provider_callback_data { JavaVM *jvm; struct aws_credentials_provider *provider; jweak java_crt_credentials_provider; jobject jni_delegate_credential_handler; }; static void s_callback_data_clean_up( JNIEnv *env, struct aws_allocator *allocator, struct aws_credentials_provider_callback_data *callback_data) { (*env)->DeleteWeakGlobalRef(env, callback_data->java_crt_credentials_provider); if (callback_data->jni_delegate_credential_handler != NULL) { (*env)->DeleteGlobalRef(env, callback_data->jni_delegate_credential_handler); } aws_mem_release(allocator, callback_data); } static void s_on_shutdown_complete(void *user_data) { struct aws_credentials_provider_callback_data *callback_data = user_data; AWS_LOGF_DEBUG(AWS_LS_AUTH_CREDENTIALS_PROVIDER, "Credentials providers shutdown complete"); // Tell the Java credentials providers that shutdown is done. This lets it release its references. /********** JNI ENV ACQUIRE **********/ JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; } jobject java_crt_credentials_provider = (*env)->NewLocalRef(env, callback_data->java_crt_credentials_provider); if (java_crt_credentials_provider != NULL) { (*env)->CallVoidMethod( env, java_crt_credentials_provider, credentials_provider_properties.on_shutdown_complete_method_id); (*env)->DeleteLocalRef(env, java_crt_credentials_provider); AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); } struct aws_allocator *allocator = aws_jni_get_allocator(); // We're done with this callback data, clean it up. JavaVM *jvm = callback_data->jvm; s_callback_data_clean_up(env, allocator, callback_data); aws_jni_release_thread_env(jvm, env); /********** JNI ENV RELEASE **********/ } 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) { (void)jni_class; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_static_options options; AWS_ZERO_STRUCT(options); options.access_key_id = aws_jni_byte_cursor_from_jbyteArray_acquire(env, access_key_id); options.secret_access_key = aws_jni_byte_cursor_from_jbyteArray_acquire(env, secret_access_key); if (session_token) { options.session_token = aws_jni_byte_cursor_from_jbyteArray_acquire(env, session_token); } options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; struct aws_credentials_provider *provider = aws_credentials_provider_new_static(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create static credentials provider"); } else { callback_data->provider = provider; } aws_jni_byte_cursor_from_jbyteArray_release(env, access_key_id, options.access_key_id); aws_jni_byte_cursor_from_jbyteArray_release(env, secret_access_key, options.secret_access_key); if (session_token) { aws_jni_byte_cursor_from_jbyteArray_release(env, session_token, options.session_token); } return (jlong)provider; } JNIEXPORT jlong JNICALL Java_software_amazon_awssdk_crt_auth_credentials_DefaultChainCredentialsProvider_defaultChainCredentialsProviderNew( JNIEnv *env, jclass jni_class, jobject java_crt_credentials_provider, jlong bootstrapHandle) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_chain_default_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; struct aws_credentials_provider *provider = aws_credentials_provider_new_chain_default(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create default credentials provider chain"); } else { callback_data->provider = provider; } return (jlong)provider; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_profile_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle; if (profile_name_override) { options.profile_name_override = aws_jni_byte_cursor_from_jbyteArray_acquire(env, profile_name_override); } if (config_file_name_override) { options.config_file_name_override = aws_jni_byte_cursor_from_jbyteArray_acquire(env, config_file_name_override); } if (credentials_file_name_override) { options.credentials_file_name_override = aws_jni_byte_cursor_from_jbyteArray_acquire(env, credentials_file_name_override); } struct aws_credentials_provider *provider = aws_credentials_provider_new_profile(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create profile credentials provider"); } else { callback_data->provider = provider; } if (profile_name_override) { aws_jni_byte_cursor_from_jbyteArray_release(env, profile_name_override, options.profile_name_override); } if (config_file_name_override) { aws_jni_byte_cursor_from_jbyteArray_release(env, config_file_name_override, options.config_file_name_override); } if (credentials_file_name_override) { aws_jni_byte_cursor_from_jbyteArray_release( env, credentials_file_name_override, options.credentials_file_name_override); } return (jlong)provider; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_ecs_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle; if (host) { options.host = aws_jni_byte_cursor_from_jbyteArray_acquire(env, host); } if (path_and_query) { options.path_and_query = aws_jni_byte_cursor_from_jbyteArray_acquire(env, path_and_query); } if (auth_token) { options.auth_token = aws_jni_byte_cursor_from_jbyteArray_acquire(env, auth_token); } struct aws_credentials_provider *provider = aws_credentials_provider_new_ecs(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create ECS credentials provider"); } else { callback_data->provider = provider; } if (host) { aws_jni_byte_cursor_from_jbyteArray_release(env, host, options.host); } if (path_and_query) { aws_jni_byte_cursor_from_jbyteArray_release(env, path_and_query, options.path_and_query); } if (auth_token) { aws_jni_byte_cursor_from_jbyteArray_release(env, auth_token, options.auth_token); } return (jlong)provider; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_sts_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle; options.creds_provider = (struct aws_credentials_provider *)creds_provider; if (role_arn) { options.role_arn = aws_jni_byte_cursor_from_jbyteArray_acquire(env, role_arn); } if (session_name) { options.session_name = aws_jni_byte_cursor_from_jbyteArray_acquire(env, session_name); } options.duration_seconds = (uint16_t)aws_timestamp_convert(duration_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_SECS, NULL); struct aws_credentials_provider *provider = aws_credentials_provider_new_sts(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create STS credentials provider"); } else { callback_data->provider = provider; } if (role_arn) { aws_jni_byte_cursor_from_jbyteArray_release(env, role_arn, options.role_arn); } if (session_name) { aws_jni_byte_cursor_from_jbyteArray_release(env, session_name, options.session_name); } return (jlong)provider; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_sts_web_identity_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrapHandle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; options.tls_ctx = (struct aws_tls_ctx *)tls_context_handle; struct aws_credentials_provider *provider = aws_credentials_provider_new_sts_web_identity(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create STS web identity credentials provider"); } else { callback_data->provider = provider; } return (jlong)provider; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_tls_connection_options tls_connection_options; AWS_ZERO_STRUCT(tls_connection_options); aws_tls_connection_options_init_from_ctx(&tls_connection_options, (struct aws_tls_ctx *)tls_context_handle); struct aws_credentials_provider_x509_options options; AWS_ZERO_STRUCT(options); options.bootstrap = (struct aws_client_bootstrap *)bootstrap_handle; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; options.tls_connection_options = &tls_connection_options; options.thing_name = aws_jni_byte_cursor_from_jbyteArray_acquire(env, thing_name); options.role_alias = aws_jni_byte_cursor_from_jbyteArray_acquire(env, role_alias); options.endpoint = aws_jni_byte_cursor_from_jbyteArray_acquire(env, endpoint); struct aws_tls_connection_options proxy_tls_connection_options; AWS_ZERO_STRUCT(proxy_tls_connection_options); struct aws_http_proxy_options proxy_options; AWS_ZERO_STRUCT(proxy_options); aws_http_proxy_options_jni_init( env, &proxy_options, proxy_connection_type, &proxy_tls_connection_options, jni_proxy_host, jni_proxy_port, jni_proxy_authorization_username, jni_proxy_authorization_password, jni_proxy_authorization_type, (struct aws_tls_ctx *)jni_proxy_tls_context); if (jni_proxy_host != NULL) { options.proxy_options = &proxy_options; } struct aws_credentials_provider *provider = aws_credentials_provider_new_x509(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create X509 credentials provider"); } else { callback_data->provider = provider; } aws_jni_byte_cursor_from_jbyteArray_release(env, thing_name, options.thing_name); aws_jni_byte_cursor_from_jbyteArray_release(env, role_alias, options.role_alias); aws_jni_byte_cursor_from_jbyteArray_release(env, endpoint, options.endpoint); aws_http_proxy_options_jni_clean_up( env, &proxy_options, jni_proxy_host, jni_proxy_authorization_username, jni_proxy_authorization_password); aws_tls_connection_options_clean_up(&tls_connection_options); return (jlong)provider; } 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) { (void)jni_class; aws_cache_jni_ids(env); if (native_cached_provider == 0) { aws_jni_throw_runtime_exception( env, "CachedCredentialsProviderials.cachedCredentialsProviderNew: cached provider is null"); return 0; } struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider_cached_options options; AWS_ZERO_STRUCT(options); options.refresh_time_in_milliseconds = aws_timestamp_convert(cached_duration_in_seconds, AWS_TIMESTAMP_SECS, AWS_TIMESTAMP_MILLIS, NULL); options.source = (struct aws_credentials_provider *)native_cached_provider; options.shutdown_options.shutdown_callback = s_on_shutdown_complete; options.shutdown_options.shutdown_user_data = callback_data; struct aws_credentials_provider *provider = aws_credentials_provider_new_cached(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create cached credentials provider"); } else { callback_data->provider = provider; } return (jlong)provider; } static int s_credentials_provider_delegate_get_credentials( void *delegate_user_data, aws_on_get_credentials_callback_fn callback, void *callback_user_data) { struct aws_credentials_provider_callback_data *callback_data = delegate_user_data; int return_value = AWS_OP_ERR; /********** JNI ENV ACQUIRE **********/ JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return AWS_OP_ERR; } // Fetch credentials from java jobject java_credentials = (*env)->CallObjectMethod( env, callback_data->jni_delegate_credential_handler, credentials_handler_properties.on_handler_get_credentials_method_id); if (aws_jni_check_and_clear_exception(env)) { aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE); goto done; } struct aws_credentials *native_credentials = aws_credentials_new_from_java_credentials(env, java_credentials); if (!native_credentials) { aws_jni_throw_runtime_exception(env, "Failed to create native credentials"); // error has been raised from creating function goto done; } callback(native_credentials, AWS_ERROR_SUCCESS, callback_user_data); aws_credentials_release(native_credentials); return_value = AWS_OP_SUCCESS; done: (*env)->DeleteLocalRef(env, java_credentials); aws_jni_release_thread_env(callback_data->jvm, env); /********** JNI ENV RELEASE **********/ return return_value; } 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, java_crt_credentials_provider); callback_data->jni_delegate_credential_handler = (*env)->NewGlobalRef(env, jni_delegate_credential_handler); struct aws_credentials_provider_delegate_options options = { .get_credentials = s_credentials_provider_delegate_get_credentials, .delegate_user_data = callback_data, .shutdown_options = { .shutdown_callback = s_on_shutdown_complete, .shutdown_user_data = callback_data, }, }; jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); struct aws_credentials_provider *provider = aws_credentials_provider_new_delegate(allocator, &options); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create delegate credentials provider"); } else { callback_data->provider = provider; } return (jlong)provider; } static int s_fill_in_logins(struct aws_array_list *logins, struct aws_byte_cursor marshalled_logins) { struct aws_byte_cursor logins_cursor = marshalled_logins; uint32_t field_len = 0; while (logins_cursor.len > 0) { if (!aws_byte_cursor_read_be32(&logins_cursor, &field_len)) { return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } struct aws_byte_cursor identity_provider_name = aws_byte_cursor_advance(&logins_cursor, field_len); if (!aws_byte_cursor_read_be32(&logins_cursor, &field_len)) { return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); } struct aws_byte_cursor identity_provider_token = aws_byte_cursor_advance(&logins_cursor, field_len); struct aws_cognito_identity_provider_token_pair login_pair = { .identity_provider_name = identity_provider_name, .identity_provider_token = identity_provider_token, }; aws_array_list_push_back(logins, &login_pair); } return AWS_OP_SUCCESS; } JNIEXPORT jlong JNICALL 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) { (void)jni_class; (void)env; aws_cache_jni_ids(env); struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider *provider = NULL; struct aws_credentials_provider_callback_data *callback_data = NULL; struct aws_tls_connection_options proxy_tls_connection_options; AWS_ZERO_STRUCT(proxy_tls_connection_options); struct aws_http_proxy_options proxy_options; AWS_ZERO_STRUCT(proxy_options); struct aws_byte_cursor endpoint_cursor; AWS_ZERO_STRUCT(endpoint_cursor); struct aws_byte_cursor identity_cursor; AWS_ZERO_STRUCT(identity_cursor); struct aws_byte_cursor custom_role_arn_cursor; AWS_ZERO_STRUCT(custom_role_arn_cursor); struct aws_byte_cursor logins_cursor; AWS_ZERO_STRUCT(logins_cursor); struct aws_array_list logins; aws_array_list_init_dynamic(&logins, allocator, 0, sizeof(struct aws_cognito_identity_provider_token_pair)); if (endpoint == NULL || identity == NULL) { goto done; } endpoint_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, endpoint); identity_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, identity); callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_callback_data)); jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); callback_data->java_crt_credentials_provider = (*env)->NewWeakGlobalRef(env, crt_credentials_provider); struct aws_credentials_provider_cognito_options options = { .shutdown_options = { .shutdown_callback = s_on_shutdown_complete, .shutdown_user_data = callback_data, }, .endpoint = endpoint_cursor, .identity = identity_cursor, .bootstrap = (void *)native_bootstrap, .tls_ctx = (void *)native_tls_context, }; if (custom_role_arn != NULL) { custom_role_arn_cursor = aws_jni_byte_cursor_from_jstring_acquire(env, custom_role_arn); options.custom_role_arn = &custom_role_arn_cursor; } if (marshalled_logins != NULL) { logins_cursor = aws_jni_byte_cursor_from_jbyteArray_acquire(env, marshalled_logins); if (s_fill_in_logins(&logins, logins_cursor)) { goto done; } options.logins = logins.data; options.login_count = aws_array_list_length(&logins); } if (proxy_host != NULL) { aws_http_proxy_options_jni_init( env, &proxy_options, proxy_connection_type, &proxy_tls_connection_options, proxy_host, proxy_port, proxy_authorization_username, proxy_authorization_password, proxy_authorization_type, (struct aws_tls_ctx *)native_proxy_tls_context); options.http_proxy_options = &proxy_options; } provider = aws_credentials_provider_new_cognito(allocator, &options); if (provider != NULL) { callback_data->provider = provider; } done: aws_jni_byte_cursor_from_jstring_release(env, endpoint, endpoint_cursor); aws_jni_byte_cursor_from_jstring_release(env, identity, identity_cursor); aws_jni_byte_cursor_from_jstring_release(env, custom_role_arn, custom_role_arn_cursor); aws_jni_byte_cursor_from_jbyteArray_release(env, marshalled_logins, logins_cursor); aws_http_proxy_options_jni_clean_up( env, &proxy_options, proxy_host, proxy_authorization_username, proxy_authorization_password); aws_array_list_clean_up(&logins); if (provider == NULL) { s_callback_data_clean_up(env, allocator, callback_data); aws_jni_throw_runtime_exception(env, "Failed to create native cognito credentials provider"); } return (jlong)provider; } JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_auth_credentials_CredentialsProvider_credentialsProviderDestroy( JNIEnv *env, jclass jni_cp, jobject cp_object, jlong cp_addr) { (void)jni_cp; (void)cp_object; aws_cache_jni_ids(env); struct aws_credentials_provider *provider = (struct aws_credentials_provider *)cp_addr; if (!provider) { aws_jni_throw_runtime_exception( env, "CredentialsProvider.credentialsProviderDestroy: instance should be non-null at destruction time"); return; } aws_credentials_provider_release(provider); } struct aws_credentials_provider_get_credentials_callback_data { JavaVM *jvm; struct aws_credentials_provider *provider; jobject java_crt_credentials_provider; jobject java_credentials_future; }; static void s_cp_callback_data_clean_up( struct aws_credentials_provider_get_credentials_callback_data *callback_data, JNIEnv *env) { if (callback_data == NULL || env == NULL) { return; } (*env)->DeleteGlobalRef(env, callback_data->java_crt_credentials_provider); (*env)->DeleteGlobalRef(env, callback_data->java_credentials_future); aws_credentials_provider_release(callback_data->provider); // We're done with this callback data, free it. aws_mem_release(aws_jni_get_allocator(), callback_data); } static void s_on_get_credentials_callback(struct aws_credentials *credentials, int error_code, void *user_data) { (void)error_code; struct aws_credentials_provider_get_credentials_callback_data *callback_data = user_data; /********** JNI ENV ACQUIRE **********/ JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm); if (env == NULL) { /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */ return; } jobject java_credentials = NULL; if (credentials) { java_credentials = aws_java_credentials_from_native_new(env, credentials); } (*env)->CallVoidMethod( env, callback_data->java_crt_credentials_provider, credentials_provider_properties.on_get_credentials_complete_method_id, callback_data->java_credentials_future, java_credentials); AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env)); if (java_credentials != NULL) { (*env)->DeleteLocalRef(env, java_credentials); } JavaVM *jvm = callback_data->jvm; s_cp_callback_data_clean_up(callback_data, env); aws_jni_release_thread_env(jvm, env); /********** JNI ENV RELEASE **********/ } JNIEXPORT void JNICALL 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) { (void)jni_cp; aws_cache_jni_ids(env); struct aws_credentials_provider *provider = (struct aws_credentials_provider *)native_credentials_provider; if (!provider) { aws_jni_throw_runtime_exception( env, "CredentialsProvider.credentialsProviderGetCredentials: instance should be non-null"); return; } if (java_crt_credentials_provider == NULL || java_credentials_future == NULL) { aws_jni_throw_runtime_exception( env, "CredentialsProvider.credentialsProviderGetCredentials: called with null parameters"); return; } struct aws_allocator *allocator = aws_jni_get_allocator(); struct aws_credentials_provider_get_credentials_callback_data *callback_data = aws_mem_calloc(allocator, 1, sizeof(struct aws_credentials_provider_get_credentials_callback_data)); callback_data->java_crt_credentials_provider = (*env)->NewGlobalRef(env, java_crt_credentials_provider); callback_data->java_credentials_future = (*env)->NewGlobalRef(env, java_credentials_future); callback_data->provider = provider; jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm); AWS_FATAL_ASSERT(jvmresult == 0); aws_credentials_provider_acquire(provider); if (aws_credentials_provider_get_credentials(provider, s_on_get_credentials_callback, callback_data)) { aws_jni_throw_runtime_exception(env, "CrtCredentialsProvider.credentialsProviderGetCredentials: call failure"); /* callback will not be invoked on failure, clean up the resource here. */ s_cp_callback_data_clean_up(callback_data, env); } } #if UINTPTR_MAX == 0xffffffff # if defined(_MSC_VER) # pragma warning(pop) # else # pragma GCC diagnostic pop # endif #endif