blob: 98c1421309e41bc0cffdf8bc97d5d69c79ac2da1 [file] [log] [blame] [edit]
/**
* 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 <http_proxy_options.h>
#include <jni.h>
#include <string.h>
#include <aws/auth/credentials.h>
#include <aws/common/clock.h>
#include <aws/common/string.h>
#include <aws/http/connection.h>
#include <aws/http/proxy.h>
#include <aws/io/tls_channel_handler.h>
/* 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